力扣刷题记录2

376.摆动序列

感觉没什么,就是检测拐点

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {

           //0 is equal, 
           //1 is up,
           //2 is down
           //-1 is uninialize
           int is_up = -1;
           vector<int> reslut;

           if(nums.size() < 1){
               return nums.size();
           }

           int fisrt = nums.at(0);

           for(int i=0; i<nums.size(); i++){

               int current = nums.at(i);
               int next;

               if(i + 1 < nums.size()){
                  next = nums.at(i+1);
               }
               else{
                   break;
               }

               if(is_up == -1){

                   if(next > current){
                       is_up = 1;
                       reslut.push_back(fisrt);
                   }

                   if(next < current){
                       is_up = 2;
                       reslut.push_back(fisrt);
                   }
              }

              if(is_up == 1){
                  if(next >= current){
                          continue;
                       }
                       else{
                          reslut.push_back(current);
                          is_up = 2;
                       }
                   }

             if(is_up == 2){
                    if(next > current){
                       reslut.push_back(current);
                       is_up = 1;
                   }
                   else{
                       continue;
                   }
                }

           }

           int last_value = nums.at(nums.size() - 1);
           reslut.push_back(last_value);

          return reslut.size();
    }
};
  1. 斐波那契数

效率不是很高

class Solution {
public:

    int fib(int n) {
        
        if(n <= 0){
            return 0;
        }

        if(n == 1){
            return 1;
        }

        if(n > 1){
            return fib(n-1) + fib(n-2);
        }

        return 0;
    }
};

70.爬楼梯

使用递归比较耗时,能不用尽量不用,虽然比较好理解

class Solution {

private:
    int dp[50];

public:

    int climbStairs(int n) {

         dp[1]=1;
         dp[2]=2;
         for(int i=3; i<=n; i++){
             dp[i]=dp[i-1] + dp[i-2];
         }

         return dp[n];

    }
};

746.使用最小花费爬楼梯

class Solution {
public:

    int minCostClimbingStairs(vector<int>& cost) {

         int count = cost.size() - 1;
         int bt_cost[1000];

         bt_cost[0] = cost.at(0);

        if(count < 1){
             return cost.at(0);
         }

         bt_cost[1] = std::min(bt_cost[0], cost.at(1));

         if(count < 2){
             return bt_cost[count];
         }

         bt_cost[2] = std::min(bt_cost[0]+cost.at(2), cost.at(1));

         for(int i=3; i<cost.size(); i++){
             bt_cost[i] = std::min(bt_cost[i-1] + cost.at(i),
                                   bt_cost[i-2] + cost.at(i-1));
         }

         return bt_cost[count];

    }
};

62.不同路径

class Solution {
public:

    int uniquePaths(int m, int n) {

        int data[m][n];

        for(int i=0; i<m;i++){
            for(int j=0; j<n; j++){

                if(i == 0 || j == 0){
                    data[i][j] = 1;
                    continue;
                }

                data[i][j] = data[i-1][j] + data[i][j-1];
            }
        }

        return data[m-1][n-1];

    }
};

63.不同路径2

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {

        int m = obstacleGrid.size();
        int n = obstacleGrid.at(0).size();

        int data[m][n];

        if(obstacleGrid.at(0).at(0) == 1){
            data[0][0] = 0;
        }
        else{
            data[0][0] = 1;
        }

        for(int i=0; i<m;i++){
            for(int j=0; j<n; j++){

                if(obstacleGrid.at(i).at(j) == 1){
                    data[i][j] = 0;
                    continue;
                }
                
                int part_1 = 0;
                if(i-1 >= 0){
                    part_1 = data[i-1][j];
                }

                int part_2 = 0;
                if(j-1 >=0){
                    part_2 = data[i][j-1];
                }

                if(i==0 && j==0){
                    continue;
                }
                else{
                    data[i][j] = part_1 + part_2;
                }
                
            }
        }

        return data[m-1][n-1];

    }
};

343.整数拆分

class Solution {
public:
    int integerBreak(int n) {

         if(n==1){
             return 0;
         }

         if(n==2){
             return 1;
         }

         if(n==3){
             return 2;
         }
        
         //else
         int result[n+1];

         result[1] = 0;
         result[2] = 2;
         result[3] = 3;
         result[4] = 4;

         for(int i=5; i<=n; i++){

             int time = n/3;
             int last = n%3;
             
             if(last == 1){
                 time--;
                 last += 3;
             }

             result[i] = 1;
             while(time > 0){
                 result[i] *= 3;
                 time--;
             }

             if(last == 0){
                 return result[i];
             }
             else{
                 result[i] *= result[last];
             }
         }

         return result[n];
    }
};

96.不同的二叉搜索树

class Solution {
public:

    int numTrees(int n) {

         if(n==1){
             return 1;
         }

         int tree_num[n+1];
         tree_num[0] = 1;
         tree_num[1] = 1;
         tree_num[2] = 2;
        
         for(int i=3; i<=n; i++){

             tree_num[i] = 0;
             for(int j=1; j<=i; j++){

                 int left = j-1;
                 int right = i-j;

                 tree_num[i] += (tree_num[left]*tree_num[right]);
             }
         }

         return tree_num[n];
    }
};

416 分割等和子集

class Solution {
public:

    bool canPartition(vector<int>& nums) {

         int sum = 0;
         for(auto it : nums){
             sum += it;
         }

         if(sum%2 != 0) return false;

         int target = sum/2;

         int bag[nums.size()][target+1];

         int first = nums.at(0);
         for(int j=0; j<target+1; j++){
             bag[0][j] = 0;
             if(j == first){
                 bag[0][j] = 1;
             }
         }

         for(int i=1; i<nums.size(); i++){

              int value = nums.at(i);

              for(int j=0; j<target+1; j++){
                    
                 if(bag[i-1][j] == 0){
                    if(value <= target && value == j){
                        bag[i][j] = 1;
                    }
                    else{

                        if(bag[i][j] == 1){
                           continue;
                        }
                        else{
                            bag[i][j] = 0;
                        }                        
                    } 
                 }
                 else{
                   int value_new = j + value;
                   bag[i][j] = 1;
 
                   if(value_new <= target){
                       bag[i][value_new] = 1;
                   }
                 }

                 if(bag[i][target] == 1){
                     return true;
                 }
              }
         }

       if(bag[nums.size()-1][target] == 1){
           return true;
       }
       else{
           return false;
       }

    }
};

494.目标和

class Solution {
public:

    int total_num = 0;

    void backtrace(vector<int>& nums, int sum, int index, int target){

           int value = 0; 
           if(index == nums.size() - 1 ){
               value = nums.at(index);

               if((sum+value) == target){
                   total_num++;   
               }

               if((sum-value) == target){
                   total_num++;
               }

               return;
           }
           else{

               value = nums.at(index);

               backtrace(nums, sum+value, index+1, target);
               backtrace(nums, sum+value*(-1), index+1, target);
           }
    }


    int findTargetSumWays(vector<int>& nums, int target) {

        backtrace(nums, 0, 0, target);

        return total_num;

    }
};

377.组合总和4

中途会有超出的情况,不计算即可。

class Solution {
public:



     //0 1 2 3 4 5
     //1 
     //  1    
     //    2 
     //      4  
     //          7     
     //            10                 


    int combinationSum4(vector<int>& nums, int target) {

             const int a = target + 1;
             int bag[a];

             for(int i=1; i<a; i++){
                 bag[i] = 0;
             }

             bag[0] = 1;

             for(int i=1; i<=target; i++){
                 for(int j=0; j<nums.size(); j++){
                     
                      if(i>=nums.at(j) && bag[i] < INT_MAX-bag[i-nums.at(j)]){
                        
                          //if(bag[i] > INT_MAX-bag[i-nums.at(j)]){
                          //    return bag[i];
                          //}

                          bag[i] += bag[i-nums.at(j)]; 
                     }
                 }
             }

             return bag[321];
    }
};

322.零钱兑换

自己通过的第一个复杂一些的动态规划

class Solution {
public:

    //1 2 3 4 5 6 7 8 9 10 11
    //1 1 2 2 1 2 2 3 3  2  1 

    int coinChange(vector<int>& coins, int amount) {

           if(amount == 0){
               return 0;
           }

           int dp[amount+1];

           for(int i=0; i<amount+1; i++){
               dp[i] = 0;
           }

           for(int i=0; i<coins.size(); i++){
               
               int value = coins.at(i);

               if(value > amount){
                   continue;
               }
               dp[value] = 1; 
           }

           for(int i=0; i<amount+1; i++){

               if(dp[i] != 0){
                   continue;
               }

               int min_value = amount;
               for(int j=0; j<coins.size(); j++){
                   if(i>coins.at(j)){

                       if(dp[i-coins.at(j)] == 0){
                           //dp[i] = -1;
                           continue;
                       }

                       dp[i] = dp[i-coins.at(j)] + 1;

                       if(dp[i] < min_value){
                           min_value = dp[i];
                       }
                   }
               }

               dp[i] = std::min(min_value,dp[i]);
           }

           if(dp[amount] == 0){
               return -1;
           }

           return dp[amount];

    }
};

279.完全平方数

class Solution {
public:

    //1  4  9  16 

    //1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    //1 2 3 1 2 3 4 2    1                   1

    int numSquares(int n) {

        int dp[n+1];

        for(int i=0; i<n+1; i++){
            dp[i] = 0;
        }

        int d=1;
        while(d*d <= n){
            dp[d*d] = 1;
            d++;
        }

        for(int i=2; i<n+1; i++){
            
            if(dp[i] != 0){
                continue;
            }

            int min_count = n;
            for(int j=1; j<n+1; j++){

                 if(i > j*j){
                     dp[i] = dp[i-j*j] + dp[j*j];

                     if(dp[i] < min_count){
                         min_count = dp[i];
                     }
                 }
                 else{
                     break;
                 }

            }

            dp[i] = std::min(dp[i], min_count);
        }

        return dp[n];

    }
};

139.单词拆分

不是自己写的,官方的版本

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {

        auto wordDictSet = unordered_set<string>();
        for(auto word: wordDict){
            wordDictSet.insert(word);
        }

        auto dp = vector<bool>(s.size()+1);
        dp[0] = true;
        for(int i=1; i<=s.size()+1; i++){
             for(int j=0; j<i; j++){
                 if(dp[j] == true
                 && wordDictSet.find(s.substr(j,i-j)) != wordDictSet.end()){
                     dp[i] = true;
                     break;
                 }
             }
        }

        return dp[s.size()];
    }
};

121.买卖股票的最佳时机

感觉和动规没有关系

class Solution {
public:

    // dp[0] 0 7 7
    // dp[1] 0 1 0
    // dp[2] 4 1 4
    // dp[3] 3 1 2

    int maxProfit(vector<int>& prices) {

        int max_monry = 0;
        int min_value = INT_MAX;
        int money = 0;

            for(int i=0; i<prices.size(); i++){
                 
                  if(prices.at(i) < min_value){
                      min_value = prices.at(i);
                  }

                  if(prices.at(i) > min_value){

                       money = prices.at(i) - min_value;

                       if(money > max_monry){
                           max_monry = money;
                       }
                  }
            }

            return max_monry;

    }
};

122.买卖股票的最佳时机2

官方的,这么简单,自己写的还要检测上升和下降

class Solution {
public:
    int maxProfit(vector<int>& prices) {

           int reault = 0;
           for(int i=1; i<prices.size(); i++){
               reault += max(prices[i] - prices[i-1], 0);
           }

           return reault;

    }
};

123.买卖股票的最佳时机

参考官网

class Solution {
public:
    int maxProfit(vector<int>& prices) {

        int n = prices.size();
        int buy1 = -prices[0], sell1 = 0;
        int buy2 = -prices[0], sell2 = 0;

        for (int i = 1; i < n; ++i) {
            buy1 = max(buy1, -prices[i]);
            sell1 = max(sell1, buy1 + prices[i]);
            
            buy2 = max(buy2, sell1 - prices[i]);
            sell2 = max(sell2, buy2 + prices[i]);
        }
        return sell2;

    }
};

388.买股票的最佳时机4

自己写的开窍版本

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {

        int n = prices.size();

        int buy[k];
        int sell[k];

        for(int i=0; i<k; i++){
            buy[i] = -prices[0];
            sell[i] = 0;
        }

        for (int i = 1; i < n; ++i) {

            buy[0] = max(buy[0], -prices[i]);
            sell[0] = max(sell[0], buy[0] + prices[i]);

            for(int j=0; j<k-1; j++){
               buy[j+1] = max(buy[j+1], sell[j] - prices[i]);
               sell[j+1] = max(sell[j+1], buy[j+1] + prices[i]);
            }

        }
        return sell[k-1];

    }
};

714.买卖股票的最佳时机含手续费

自己写的,过了

class Solution {
public:

        //   dp[i][0] dp[i+1][0] //0 持有股票
        //   dp[i][1] dp[i+1][1] //1 卖出股票

        //   dp[0][0] = 0;             //0 没有持有股票
        //   dp[0][1] = -prices(0);    //1 买入股票
        //   dp[0][2] = 0;             //2 卖出股票

        //   dp[1][0] = max(dp[0][2], dp[0][0])
        //   dp[1][1] = max(dp[0][0]-prices(i), dp[0][1], dp[0][2]-prices(i));
        //   dp[1][2] = dp[0][1] + prices(i) - fee;
          
    int maxProfit(vector<int>& prices, int fee) {

          int dp[prices.size()][3];

          dp[0][0] = 0;
          dp[0][1] = -prices.at(0);
          dp[0][2] = 0;

          for(int i=1; i<prices.size(); i++){
              dp[i][0] = max(dp[i-1][2], dp[i-1][0]);
              dp[i][1] = max(max(dp[i-1][0]-prices.at(i),
                             dp[i-1][1]),
                             dp[i-1][2]-prices.at(i));
              dp[i][2] = dp[i-1][1] + prices.at(i) - fee;
          }

          return max(dp[prices.size()-1][0], dp[prices.size()-1][2]);
    }
};

300.最长递增子序列

最笨方法

class Solution {
public:

    // dp[0] 1
    // dp[1] 2
    // dp[2] 2
    // dp[3] 3
    // dp[4] 3
    // dp[5] 3
    // dp[6] 4 

    int lengthOfLIS(vector<int>& nums) {

          int dp[nums.size()];

          dp[0] = 1;
          int max_count = 1;

          for(int i=1; i<nums.size(); i++)
          {
              dp[i] = 1;
              for(int j=i-1; j>=0; j--){
                  if(nums.at(i) > nums.at(j)){
                      dp[i] = max(dp[j]+1, dp[i]);
                      if(dp[i] > max_count){
                          max_count = dp[i];
                      }
                  }
              }
          }

        return max_count;
    }
};
  1. 最长连续递增序列

感觉不用递归

class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {

           int up_step = 1;
           int max_up_step = 0;
           for(int i=1; i<nums.size(); i++){

                if(nums.at(i) > nums.at(i-1)){
                    up_step++;
                }
                else{
                    max_up_step = max(max_up_step, up_step);
                    up_step = 1;
                }
           }

           max_up_step = max(max_up_step, up_step);

           return max_up_step;

    }
};

动规效率也一般,不是自己写的

class Solution {
public:
    int findLength(vector<int>& A, vector<int>& B) {
        int n = A.size(), m = B.size();
        vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
        int ans = 0;
        for (int i = n - 1; i >= 0; i--) {
            for (int j = m - 1; j >= 0; j--) {
                dp[i][j] = A[i] == B[j] ? dp[i + 1][j + 1] + 1 : 0;
                ans = max(ans, dp[i][j]);
            }
        }
        return ans;
    }
};

1143.最长公共子序列

更像找规律

class Solution {
public:
    int longestCommonSubsequence(string text1, string text2) {
        int m = text1.length(), n = text2.length();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (int i = 1; i <= m; i++) {
            char c1 = text1.at(i - 1);
            for (int j = 1; j <= n; j++) {
                char c2 = text2.at(j - 1);
                if (c1 == c2) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];
    }
};

   0  1  2  3  4  5  6
0  0  0  0  0  0  0  0
1  0  0  0  0  0  0  0
2  1  1  1  1  1  1  1
3  1  1  1  1  1  2  2
4  1  1  1  1  1  2  2
5  1  1  1  2  2  2  2

1035.不相交的线

同上,只是换了一种形式

class Solution {
public:
    int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {

        int m = nums1.size(), n = nums2.size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (int i = 1; i <= m; i++) {
            int c1 = nums1.at(i - 1);
            for (int j = 1; j <= n; j++) {
                int c2 = nums2.at(j - 1);
                if (c1 == c2) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[m][n];

    }
};

392.判断子序列

没有用动规

class Solution {
public:
    bool isSubsequence(string s, string t) {

        int i = 0;
        int j = 0;

        while(j<t.length() && i<s.length()){

           if(s[i] == t[j]){
               i++;
               j++;
           }
           else{
               j++;
           }
        }

        if(i == s.length()){
            return true;
        }
        else{
            return false;
        }

    }
};

最长公共子序列的翻版

class Solution {
public:
    int minDistance(string word1, string word2) {

        int m = word1.length(), n = word2.length();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (int i = 1; i <= m; i++) {
            char c1 = word1.at(i - 1);
            for (int j = 1; j <= n; j++) {
                char c2 = word2.at(j - 1);
                if (c1 == c2) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        return  word1.length() + word2.length() -2*dp[m][n];
    }
};

72.编辑距离
动规是如何发现的呢?抄官方

class Solution {
public:
    int minDistance(string word1, string word2) {
        int n = word1.length();
        int m = word2.length();

        // 有一个字符串为空串
        if (n * m == 0) return n + m;

        // DP 数组
        vector<vector<int>> D(n + 1, vector<int>(m + 1));

        // 边界状态初始化
        for (int i = 0; i < n + 1; i++) {
            D[i][0] = i;
        }
        for (int j = 0; j < m + 1; j++) {
            D[0][j] = j;
        }

        // 计算所有 DP 值
        for (int i = 1; i < n + 1; i++) {
            for (int j = 1; j < m + 1; j++) {
                int left = D[i - 1][j] + 1;
                int down = D[i][j - 1] + 1;
                int left_down = D[i - 1][j - 1];
                if (word1[i - 1] != word2[j - 1]) left_down += 1;
                D[i][j] = min(left, min(down, left_down));

            }
        }
        return D[n][m];
    }
};

516.最长回文子序列

想出来这个方法的人,智商best

class Solution {
public:
    int longestPalindromeSubseq(string s) {
        int n = s.length();
        vector<vector<int>> dp(n, vector<int>(n));
        for (int i = n - 1; i >= 0; i--) {
            dp[i][i] = 1;
            char c1 = s[i];
            for (int j = i + 1; j < n; j++) {
                char c2 = s[j];
                if (c1 == c2) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }
        return dp[0][n - 1];
    }
};                              3 4  44  33
    j b  b  b  a  b
  i   0  1  2  3  4 
b 0   1  2  3  3  4
b 1      1  2  2  3
b 2         1  1  3
a 3            1  1
b 4               1


你可能感兴趣的:(leetcode,算法,c++)