leetcode轮回计划20181117

  1. 306 Addtive Number
    题意:判断一个字符串能不能构成连加字符串
def isAdditiveNumber(self, num):
    n = len(num)
    for i, j in itertools.combinations(range(1, n), 2):
        a, b = num[:i], num[i:j]
        if b != str(int(b)):
            continue
        while j < n:
            c = str(int(a) + int(b))
            if not num.startswith(c, j):
                break
            j += len(c)
            a, b = b, c
        if j == n:
            return True
    return False
class Solution {
public:
    bool isAdditiveNumber(string num) {
        int size = num.size();
        if(size < 3) return false;
        for(int i = 1;i < size;++ i){
            // while(num[i] == '0' && i < size && i > 1) ++ i;
            for(int j = i + 1;j < size;++ j){
                // while(num[j] == '0' && j < size && i + 1 < j) ++ j;
                string add1 = num.substr(0,i);
                string add2 = num.substr(i,j - i);
                // cout< size) return false;
        if(result == num.substr(index,result.size())){
            return help_judge(num,index + result.size(),add2,result);
        }
        return false;
    }
    
    string help_add(string add1,string add2){
        int size1 = add1.size();
        int size2 = add2.size();
        if(size1 < size2) return help_add(add2,add1);
        int index = size1 - 1;
        int index2 = size2 - 1;
        int tmp = 0;
        while(index >= 0){
            int a1 = add1[index] - '0';
            int a2 = index2 >= 0 ? add2[index2] - '0' : 0;
            int result = a1 + a2 + tmp;
            add1[index] = to_string(result % 10)[0];
            tmp = result / 10;
            index --;
            index2 --;
        }
        if(tmp > 0) add1.insert(0,to_string(tmp));
        return add1;
    }
};
  1. 307 Range Sum Query - Mutable
    题意:线段树的经典题目
    思路:可以当做hard来做,因为涉及到了比较经典的数据结构,而且使用范围非常小,其实没必要做。要是想要知道线段树的构造和应用的话,可以看一下下面这篇文章:https://blog.csdn.net/Yaokai_AssultMaster/article/details/79599809。
  2. 309 Best Time to Buy and Sell Stock with Cooldown
    题意:股票交易,买卖之间需要有缓冲时间
    思路:构造sell,buy,rest三种情况的dp数组
class Solution {
public:
    int maxProfit(vector& prices) {
        int size = prices.size();
        if(size == 0) return 0;
        vector buy(size,0);
        vector sell(size,0);
        vector rest(size,0);
        buy[0] = prices[0] * (-1);
        sell[0] = 0;
        rest[0] = 0;
        for(int i = 1;i < size; ++ i){
            buy[i] = max(buy[i - 1],rest[i - 1] - prices[i]);
            sell[i] = max(sell[i - 1],buy[i - 1] + prices[i]);
            rest[i] = max(buy[i - 1],max(sell[i - 1],rest[i - 1]));
        }
        
        return max(buy[size - 1],max(sell[size - 1],rest[size - 1]));
    }
};
  1. 310 Minimum Height Trees
    题意:深度最小树的根节点集合
    思路:剥洋葱
class Solution {
public:
    vector findMinHeightTrees(int n, vector>& edges) {
        
        if(edges.size() == 0){
            if(n == 1) return{0};
            if(n == 2) return{0,1};
        }
        
        vector> edge(n,vector());
        for(auto a : edges){
            edge[a.first].push_back(a.second);
            edge[a.second].push_back(a.first);
        }

        vector ret;
        for(int i = 0;i < n;++ i) if(edge[i].size() == 1) ret.push_back(i);

        int num = n;
        while(num > 2){
            for(;!ret.empty();ret.pop_back()){
                int index1 = ret.back();
                int index2 = edge[index1][0];
                edge[index1].pop_back();
                if(edge[index2].size() > 1)
                    edge[index2].erase(remove(edge[index2].begin(),edge[index2].end(),index1),edge[index2].end());
                num -= 1;
            }
            
            for(int i = 0;i < n;++ i) if(edge[i].size() == 1) ret.push_back(i);
        }
        
        return ret;
    }
};
  1. 313 Super Ugly Number
    题意:给定素数列表,给出第n个这些素数可以组成的数字
    思路:直接看代码吧,假如做不出来的话。。。
class Solution {
public:
    int nthSuperUglyNumber(int n, vector& primes) {
        int size = primes.size();
        vector flag(size,0);
        vector ret(n,1);

        for(int i = 1;i < n;++ i){
            int mini = INT_MAX;
            for(int j = 0;j < size;++ j){
                while(ret[i - 1] >= primes[j] * ret[flag[j]]) flag[j] ++;
                mini = min(mini,primes[j] * ret[flag[j]]);
            }
            ret[i] = mini;
        }
        
        return ret[n - 1];
    }
};
  1. 318 Maximum Product of Word Lengths
    题意:无重复字母的单词的长度乘积最大值
    思路:使用位运算作为map
class Solution {
public:
    int maxProduct(vector& words) {
        unordered_map maxlen;
        for (string word : words) {
            int mask = 0;
            for (char c : word) mask |= 1 << (c - 'a');
            maxlen[mask] = max(maxlen[mask], (int) word.size());
        }
        int result = 0;
        for (auto a : maxlen) for (auto b : maxlen) if (!(a.first & b.first))
            result = max(result, a.second * b.second);
        return result;
    }
};
  1. 319 Bulb Switcher
    题意:关灯实验,第i次只操作i的整数的灯
    思路:return sqrt(n)
  2. 322 Coin Change
    题意:换硬币
    思路:动态规划。。。刚开始想要用分治来做,但是思路非常混乱。。。对于动态规划的理解还是需要加强。。。
class Solution {
public:
    int coinChange(vector& coins, int amount) {
        int Max = amount + 1;
        vector dp(amount + 1, Max);
        dp[0] = 0;
        for (int i = 1; i <= amount; i++) {
            for (int j = 0; j < coins.size(); j++) {
                if (coins[j] <= i) {
                    dp[i] = min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];
    }
};
  1. 324 Wiggle Sort II(3)
    题意:波浪排序
    思路:找到中间值->序号重排、
class Solution {
public:
    void wiggleSort(vector& nums) {
        int size = nums.size();
        auto midptr = nums.begin() + size / 2;
        nth_element(nums.begin(), midptr, nums.end());
        int mid = *midptr;
        // cout< mid){
                swap(A(index_odd ++), A(index ++));
            }else if(A(index) < mid){
                swap(A(index), A(index_even --));
            }else{
                index ++;
            }
        }
    }
};
  1. 332 Reconstruct Itinerary(3)
    题意:给出飞行顺序的最小字典结果
    思路:比较新奇的分治法。
class Solution {
public:
    vector findItinerary(vector> tickets) {
        map> edge;
        for(auto a : tickets) edge[a.first].insert(a.second);
        vector ret;
        divid(edge, ret, "JFK");
        reverse(ret.begin(), ret.end());
        return ret;
    }
    void divid(map>& edge, vector& ret, string s){
        while(edge[s].size()){
            string next = *edge[s].begin();
            cout<
  1. 334 Increasing Triplet Subsequence
    题意:判断数组中有没有三个升序数字
    思路:啥也别说了,我是想不出来。。。不过还挺好理解的
class Solution {
public:
    bool increasingTriplet(vector& nums) {
        int imin = INT_MAX;
        int imid = INT_MAX;
        for(auto x : nums){
            if(x <= imin) imin = x;
            else if(x <= imid) imid = x;
            else return true;
        }
        return false;
    }
};
  1. 337 House Robber III
    题意:有边的不能都遍历
    思路:使用flag辅助
class Solution {
public:
    int rob(TreeNode* root) {
        return dfs(root, false);
    }
    int dfs(TreeNode* root, bool flag) {
        if(!root) return 0;
        if(flag) return dfs(root->left,false) + dfs(root->right,false);
        else return max(root->val + dfs(root->left, true) + dfs(root->right, true), 
                        dfs(root->left,false) + dfs(root->right,false));
    }
};
  1. 338 Counting Bits
    题意:返回前n个的二进制表示中1的个数的vector,要求one-pass
    思路:简单的动态规划
class Solution {
public:
    vector countBits(int num) {
        vector ret(num + 1);
        for(int i = 0;i <= num;++ i) ret[i] = ret[i >> 1] + (1 & i);
        return ret;
    }
};
  1. 341 Flatten Nested List Iterator

你可能感兴趣的:(leetcode轮回计划20181117)