vlambda博客
学习文章列表

【每日编程-444期】Leetcode.942. 增减字符串匹配



942. 增减字符串匹配




给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length。


返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i = 0, ..., N-1,都有:


  • 如果 S[i] == "I",那么 A[i] < A[i+1]

  • 如果 S[i] == "D",那么 A[i] > A[i+1]

样例一:

输入:"IDID"
输出:[0,4,1,3,2]

样例二:

输入:"III"
输出:[0,1,2,3]

样例三:

输入:"DDI"
输出:[3,2,2,3]

解决方法:

(1)算法的基本思想:

我们首先考虑字符串中的第一个字母。如果 S[0] == 'I',那么我们只要令 A[0] = 0,就一定能满足 A[0] < A[1]。如果 S[0] == 'D',同样我们只要令 A[0] = N,就一定能满足 A[0] > A[1]。


接下来,当我们考虑 S 中剩下的 N - 1 个字母时,还剩下 N 个数可以使用,这 N 个数为 [0 .. N - 1] 或 [1 .. N]。可以发现,由于 S[0] 的值已经确定,那么剩下 S 中的 N - 1 个字母和 N 个可用的数变成了一个和原问题相同,但规模为 N - 1 的问题。即如果 S[1] == 'I',我们就令 A[1] 为剩下数中最小的那个数;如果 S[1] == 'D',我们就令 A[1] 为剩下数中最大的那个数。
我们每次会把可以使用的数的集合中的最小值或最大值取出,并放到当前的位置,因此可以使用的数的集合总是连续的,就可以非常方便的进行维护。
我们维护当前未使用的最小和最大的数,它们对应的区间为当前未使用的数的集合。从左向右扫描字符串,如果碰到 'I',就取出当前最小的数,否则取出当前最大的数。

链接:https://leetcode-cn.com/problems/two-sum/solution/zeng-jian-zi-fu-chuan-pi-pei-by-leetcode/

来源:力扣(LeetCode)

(2)代码实现:

  
    
    
  
class Solution {
public:
    vector<int> diStringMatch(string s) {
        int l = 0, r = s.size();
        vector<int> retval(s.size() + 1);
        for(int j = 0; j < s.size(); ++j){
            if(s[j] == 'I')
                retval[j] = l++;
            else
                retval[j] = r--;
        }
        retval.back() = l;
        return retval;
    }
};

明日预告:Leetcode.700.二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点和一个值。你需要在BST中找到节点值等于给定值的节点。返回以该节点为根的子树。如果节点不存在,则返回 NULL。

输入样例:

给定二叉搜索树:

4
/ \
2 7
/ \
1 3

和值: 2

输出样例:

      2
/ \
1 3
在上述示例中,如果要找的值是  5 ,但因为没有节点值为  5 ,我们应该返回  NULL
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {

    }
};