(动态规划、递归) leetcode 87. Scramble String

 

思路:用递归来做感觉比动态规划简单,题目让我们判断s1和s2是否是scramble string,则s1上(从左起计数)有一个长度为 i 的分割点将s1分为s1_l 和 s1_r 两段 分别与 s2的(从左起计数一个长度为i的) s2_l 和 s2_r 互为 scramble string;或者与 s2的(从右起计数一个长度为i的)s2.substr(s-i) 和 s2.substr(0, s-i) 互为 scramble string 。

1)C++ 中的 substr(pos, len) 表示从 索引为pos开始的子字符串,截取长度为len的子串,即子串的索引为[pos, pos+len) 注意是左闭右开区间; substr(pos) 表示从索引pos开始到字符串末尾的子字符串,即 [pos, size ) size为字符串长度,注意是左闭右开区间。

2)sort() 可以按字典序排列 string 类型的字符串。

3)== 可以用来判断两个字符串是否相同。

class Solution {
public:
    bool isScramble(string s1, string s2) {
        int s = s2.size(); 
        if(s1.size()!=s2.size())
            return false;
        if(s1==s2)
            return true;
        string str1 = s1, str2 = s2;
        sort(str1.begin(), str1.end());
        sort(str2.begin(), str2.end());
        if(str1 != str2)
            return false;
        for(int i=1; i<s1.size(); ++i){
            string st1_l = s1.substr(0, i), st1_r = s1.substr(i);
            string st2_l = s2.substr(0, i), st2_r = s2.substr(i);
            if((isScramble(st1_l, st2_l) && isScramble(st1_r, st2_r)) || ( isScramble(st1_l, s2.substr(s-i) ) && isScramble(st1_r, s2.substr(0, s-i) ) ))
                return true;
        }
        return false;
        
    }
};

 

递归:注意 / 的意思是浮点数的除法,所以要先将int型的nums转化为 double 型的 arr;每次选两个索引位置不相同的元素,进行加减乘除操作,并将结果放入数组中,然后递归求解,直到数组最后只剩下一个元素,若这个元素值为24,则返回true。最后若两层遍历结束后都没有找到最后的结果为24,则返回false。

class Solution {
public:
    bool judgePoint24(vector<int>& nums) {
        vector<double> arr(nums.begin(), nums.end());
        
        return helper(arr);
    }
    
    bool helper(vector<double>& arr){
        int size = arr.size();
        if(size == 1 )
            return (abs(arr[0] - 24) < 1e-6);
        for(int i=0; i<size; ++i){
            for(int j=0; j<size; ++j){
                if(i==j)
                    continue;  //不能取相同的元素
                vector<double> new_arr;
                for(int k=0; k<size; ++k)
                    if(k!=i && k!=j) new_arr.push_back(arr[k]);
                new_arr.push_back(-1);
                
                double a = arr[i], b = arr[j];
                
                new_arr.back() = a+b;
                if (helper(new_arr))
                    return true;
                
                new_arr.back() = a-b;
                if (helper(new_arr))
                    return true;
                
                new_arr.back() = a*b;
                if (helper(new_arr))
                    return true;
                
                new_arr.back() = a/b;
                if (helper(new_arr))
                    return true;

            }
        }
        return false;
    }
};

 

感觉这道题的题意有点难理解啊!而且难哭了 :(

1)青蛙初始在第一块石头上,假设一开始只能跳一个单位

 2)若青蛙前一步跳了k个单位,则它的下一步只能是k-1, k, k+1 个单位。且只能往前跳不能往后退。

动态规划: 使用map,它的key 表示当前石头的位置pos,value 是一个包含 jumpsize的集合set,其中每个 jumpsize 代表可以通过大小为 jumpysize 大小的一跳到达当前位置。首先对map初始化,key 为所有石头的位置,除了位置 0 对应的 value 为包含一个值 0 的集合以外(dp[0] = 0 ),其余都初始化为空集。接下来,依次遍历每个位置上的石头。对于每个currentPosition,遍历 value 中每个 jumpsize,,对于每个 jumpsize,newjumpsize 分别为 jumpsize−1,jumpsize,jumpsize+1, 判断位置 currentPosition + newjumpsize 是否存在于 map 中。如果找到了,就在位置 currentPosition + newjumpsize 对应的 value 集合里新增 newjumpsize。重复这个过程直到结束。如果在结束的时候,最后一个位置对应的集合非空,那也就意味着我们可以到达终点,如果还是空集那就意味着不能到达终点。

class Solution {
public:
    bool canCross(vector<int>& stones) {
        unordered_map<int, unordered_set<int>> dp;
        for (auto position : stones)
            dp[position] = unordered_set<int>();
        dp[0].insert(0);
        for (auto position : stones) {
            for (auto k : dp[position]) {
                // k - 1
                if (k - 1 > 0 && dp.find(position + k - 1) != dp.end())
                    dp[position + k - 1].insert(k - 1);
                // k
                if (dp.find(position + k) != dp.end())
                    dp[position + k].insert(k);
                // k + 1
                if (dp.find(position + k + 1) != dp.end())
                    dp[position + k + 1].insert(k + 1);
            }
        }
        return !dp[stones.back()].empty();
    }
};

 

 

posted @ 2019-07-20 11:24  爱学英语的程序媛  阅读(250)  评论(0编辑  收藏  举报