力扣每日一题2021 4月

(4.10)263 丑数

//递归
class Solution {
    vector<bool>dp;
public:
    bool isUgly(int n) {
       if(n==0) return false;
       if(n==1) return true;
       if(n%2!=0&&n%3!=0&&n%5!=0) return false;
       if(n%2==0)return isUgly(n/2);
       else if(n%3==0) return isUgly(n/3);
       else return isUgly(n/5);
    }
};

(4.11)264 丑数2
三指针方法 p2 p3 p5 min(res[p2]*2,res[p3]*3,res[p5]*5);

class Solution {

public:
    int nthUglyNumber(int n) {
   vector<int>res=vector<int>(n);
   res[0]=1;
   int p2,p3,p5;
   p2=p3=p5=0;

   for(int i=1;i<n;i++)
   {
       res[i]=min(min(res[p2]*2,res[p3]*3),res[p5]*5);
       if(res[i]==res[p2]*2)
        p2++;
       if(res[i]==res[p3]*3)
        p3++;
       if(res[i]==res[p5]*5)
        p5++;
   }

    
 return res[n-1];
    }
};

(4.11)1371. 每个元音包含偶数次的最长子字符串
给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 ‘a’,‘e’,‘i’,‘o’,‘u’ ,在子字符串中都恰好出现了偶数次。
输入:s = “eleetminicoworoep”
输出:13
解释:最长子字符串是 “leetminicowor” ,它包含 e,i,o 各 2 个,以及 0 个 a,u 。

维护一个位图POS保存AEIOU状态 0为偶 1为奇数
如果状态不存在POS[STATUS]保存的是该状态下的最早位置
如果状态存在 maxv=max(maxv,i+1-POS[STATUS])

class Solution {
public:
    int findTheLongestSubstring(string s) {
      char charlist[5]={'a','e','i','o','u'};
      
      vector<int> pos=vector<int>(1<<5,-1);
      int status=0;//偶为0
      pos[0]=0;
      int ans=0;
      for(int i;i<s.size();i++)
      {
          for(int j=0;j<5;j++)
          {
              if(s[i]==charlist[j])
                {
                    status^=1<<j;
                    break;
                }
          }
          if(pos[status]!=-1)
          {
              ans=max(ans,i+1-pos[status]);
          }
          else 
              pos[status]=i+1;
      }

     return ans;
    }
};

(4.11)34. 二叉树中和为某一值的路径

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
   
   vector<vector<int>>res;
   vector<int>path;

   void dfs(TreeNode* root, int target)
   {
       if(root==nullptr) return;
       //if(target<root->val) return;
        target-=root->val;
        path.push_back(root->val);
        if(target == 0 && !root -> left && !root -> right)
           { res.push_back(path);}
       dfs(root->left,target);
       dfs(root->right,target);
       path.pop_back();
       return;
   }
public:
    vector<vector<int>> pathSum(TreeNode* root, int target) {
      dfs(root,target);
      return res;

    }
};

(4.12)179. 最大数
输入:nums = [3,30,34,5,9]
输出:“9534330”

class Solution {
    vector<string>res;
    
    struct cmp{
    bool  operator()(string& a,string& b)
    {
       return (a+b)>(b+a);
    }
    };

public:
    string largestNumber(vector<int>& nums) {
     for(int i=0;i<nums.size();i++)
     {
         res.push_back(to_string(nums[i]));
     }
     
     string ans="";
     sort(res.begin(),res.end(),cmp());
     if(res[0]=="0") return "0";//排好序后开始是0 则代表为全0串 返回0
     for(auto x:res)
     {
         ans+=x;
     }
     return ans;
    }
};

(4.12)102. 二叉树层序遍历

//我的代码:
class Solution {
    queue< pair<TreeNode*,int>>q;// int层数
     vector<vector<int>>res;


public:
    vector<vector<int>> levelOrder(TreeNode* root) {
       if(root==nullptr) return res;
        res.push_back(vector<int>(1,root->val));
        q.push(make_pair(root,1));
      while(!q.empty())
       {
        TreeNode* root=q.front().first;
        int i=q.front().second; 
         if(res.size()<i+1) res.push_back(vector<int>());
        q.pop();
       if(root->left!=nullptr) 
        { q.push(make_pair(root->left,i+1));
          res[i].push_back(root->left->val);
          }

       if(root->right!=nullptr)
        { q.push(make_pair(root->right,i+1)); 
          res[i].push_back(root->right->val);
         }
       
       }
       res.pop_back();
       return res;
    }
};
//官方代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    queue<TreeNode*>q;
     vector<vector<int>>res;


public:
    vector<vector<int>> levelOrder(TreeNode* root) {
       if(root==nullptr) return res;
        q.push(root);
      while(!q.empty())
       {
        int n=q.size();//每次更新q容量 
        res.push_back(vector<int>());//更新res容量
        for(int i=0;i<n;i++)
        {
            TreeNode* node=q.front();
            res.back().push_back(node->val);
            q.pop();
            if(node->left) q.push(node->left);
            if(node->right) q.push(node->right);
        }
        }
        return res;
    }
};

(4.13)783. 二叉搜索树节点最小距离
使用二叉搜索树 中序遍历性质

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
    
    
    int last=-1;
    int min_v=INT_MAX;
    void  mids(TreeNode*root)
    {
        if(root==nullptr) return;
        if(root->left) mids(root->left);
        if(last!=-1)
        min_v=min(min_v,root->val-last);
          last=root->val;
        if(root->right) mids(root->right);
    }
public:
    int minDiffInBST(TreeNode* root) {
       mids(root);
      return min_v;
      
    }
};

(4.14)208. 实现Trie(前缀树)
采用链表类实现

class Trie {
         bool isend;
         Trie* next[26];
public:
    /** Initialize your data structure here. */
    Trie() {
     isend=false;
     memset(next,0,sizeof(next));
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* node=this;
       for(char i:word)
       {
           if(node->next[i-'a']==nullptr)
            node->next[i-'a']=new Trie();
            node=node->next[i-'a'];
       }
        node->isend=true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
      Trie* node=this;
        for(char i:word)
       {
           if(node->next[i-'a']!=nullptr)
            node=node->next[i-'a'];
            else return false;
       }
        return node->isend;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
      Trie* node=this;
        for(char i:prefix)
       {
           if(node->next[i-'a']!=nullptr)
            node=node->next[i-'a'];
            else return false;
       }
       return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie* obj = new Trie();
 * obj->insert(word);
 * bool param_2 = obj->search(word);
 * bool param_3 = obj->startsWith(prefix);
 */

(4.14) 45. 跳跃游戏

class Solution {
vector<int>dp;
public:
    int jump(vector<int>& nums) {
        int n=nums.size();
        dp.resize(n,0);
        int k;
        for(int i=0;i<n;i++)
        {
           for(int j=i+1;j<=min(nums[i]+i,n-1);j++)
             {
                 if(dp[j]==0) dp[j]=dp[i]+1;//当前状态未更新
                 else dp[j]=min(dp[i]+1,dp[j]);//取最小值更新
             }

        }

       return dp[n-1];
    }
};

(4.14) 5. 最长回文子串

class Solution {
vector<vector<bool>>dp;
public:
    string longestPalindrome(string s) {
    int n=s.size(); 
    if(n==1) return s;
    dp.resize(n,vector<bool>(n,false));
    for(int i=0;i<n;i++)
    {
        dp[i][i]=true;
    }
    int max=1;//初始长度为1
    string m=s.substr(0,1);//初始长度取第一个子串的第一个字符
    for(int i=n-1;i>=0;i--)
    {
        for(int j=i;j<n;j++)
        {
            if(i+1<n&&j-1>=0)
            {
              if((dp[i+1][j-1]||j-i==1)&&s[i]==s[j])
             {
             dp[i][j]=true;
              if(j-i+1>max) 
              {max=j-i+1;m=s.substr(i,j-i+1);}
             }
            }
        }

    }
    return m;
    }
};

队列+哈希表

class Solution {
   map<char,int>f;
   queue<char>q;
public:
    int lengthOfLongestSubstring(string s) {
      int max1=0;
      for(int i=0;i<s.size();i++)
       {
         if(f.find(s[i])!=f.end()&&f[s[i]]==1)
         {
             while(!q.empty())
             {
                if(q.front()!=s[i])
                {f[q.front()]--;
                 q.pop();}
                 else 
                 {q.pop();
                     break;}
             }
             //q.push(s[i]);
         }
        else f[s[i]]=1;
            //q.push(s[i]);
            q.push(s[i]);
            max1=max1>q.size()?max1:q.size();
       }  
       return max1;
    }
};

(4.15) 213. 邻家打舍2

class Solution {
   

    int rob1(vector<int>&nums,int i,int j)
    {
         vector<int>dp;
         dp.resize(j-i+1,0);
         dp[0]=nums[i];
         dp[1]=max(nums[i],nums[i+1]); //dp[i] 代表 打劫到当前户的最大值
        for(int k=i+2;k<=j;k++)
        {
            dp[k-i]=max(dp[k-i-2]+nums[k],dp[k-i-1]);
            //当前位置的-2位置的值+当前的财产 与 当前位置的-1位置的值 进行比较 取最大
        }
        return dp[j-i];
    }
public:
    int rob(vector<int>& nums) {
	    int n=nums.size();
         if(n==1||n==2) return *max_element(nums.begin(),nums.end());
        return max(rob1(nums,0,n-2),rob1(nums,1,n-1)); 
    }
};

(4.18)3. 无重复字符的最长子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
    if(s.size()==0) return 0;
    int l=0;
    int max_v=1;
     for(int i=0;i<s.size();i++)
    {
      
      for(int j=l;j<i;j++)
      {
           if(s[j]==s[i])
              l=j+1;
      }
      max_v=max(max_v,i-l+1);
    }
    return max_v;
    }
};

(4.18)72. 编辑距离

class Solution {
    vector<vector<int>>dp;
public:
    int minDistance(string word1, string word2) {
    int n=word1.size()+1;
    int m=word2.size()+1;

    dp.resize(n,vector<int>(m,0));
    for(int i=1;i<n;i++)
    {
        dp[i][0]=dp[i-1][0]+1;
    }
     for(int j=1;j<m;j++)
    {
        dp[0][j]=dp[0][j-1]+1;
    }
     for(int i=1;i<n;i++)
    {
        for(int j=1;j<m;j++)
        {
           if(word1[i-1]!=word2[j-1])
           dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
           else dp[i][j]=dp[i-1][j-1];
        }
    }
     return dp[n-1][m-1];

    }
};

(4.19)27. 移除元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int pos=0;
        for(int i=0;i<nums.size();i++)
        {
            
            if(nums[i]==val)
            {
             continue;
            } 
            else {nums[pos]=nums[i]; pos++;}
        }
        return pos;
    }
};

(4.19)97. 交错字符串

class Solution {
public:
    bool isInterleave(string s1, string s2, string s3) {
         
           if(s1.size()+s2.size()!=s3.size()) return false;
           int m=s1.size()+1;
           int n=s2.size()+1;
           bool dp[m][n]; 
           memset(dp,false,sizeof(dp));
           dp[0][0]=true;
           for(int i=1;i<m;i++)
           {
               dp[i][0]=dp[i-1][0]&&s1[i-1]==s3[i-1];
           }
           for(int j=1;j<n;j++)
           {
               dp[0][j]=dp[0][j-1]&&s2[j-1]==s3[j-1];
           }
        
           for(int i=1;i<m;i++)
           {
               for(int j=1;j<n;j++)
               {
                       if(dp[i-1][j]&&s1[i-1]==s3[i+j-1])
                        dp[i][j]=true;
                        if(dp[i][j-1]&&s2[j-1]==s3[i+j-1])
                        dp[i][j]=true;
                   
               }
           }
          return dp[m-1][n-1];
    }
};

(4.23)368. 最大整除子集

//dfs+回溯 超时了
 class Solution {
vector<bool>dp;
vector<int> path;
vector<int>res;
int max_v=0;
void dfs(vector<int>&nums,vector<int>path,int i)
{
    if(i>=0&&dp[i]) return;
    if(i<0) {
        if(path.size()>max_v) {res=path;max_v=path.size();}
        return;}
	if(path.size()==0) {path.push_back(nums[i]);dp[i]=true;}
    else{
        if(path[path.size()-1]%nums[i]==0||nums[i]%path[path.size()-1]==0)
         { path.push_back(nums[i]);dp[i]=true;}
    }
     dfs(nums,path,--i);
}
    
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        int n=nums.size();
        dp.resize(n,false);
         for(int i=nums.size()-1;i>=0;i--)
         {
             dfs(nums,path,i);
         }
        return res;
    }
};
//采用dp

class Solution {
int max_v;
int max_s=1;
vector<int>dp;
vector<int>res;
public:
    vector<int> largestDivisibleSubset(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int n=nums.size();
        dp.resize(n,1);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<i;j++)
            {
                if(nums[i]%nums[j]==0)
                {dp[i]=max(dp[i],dp[j]+1);}
            }
            if(dp[i]>=max_s)
            {
              max_s=dp[i];
              max_v=nums[i];
            }
        }
        if(max_v==1)
        {
            res.push_back(nums[0]); return res;
        }
        for(int i=n-1;i>=0&&max_s>0;i--)
        {
            if(dp[i]==max_s&&max_v%nums[i]==0)
            {
                res.push_back(nums[i]);
                max_s--;
                max_v=nums[i];
            }
        }  
        
        return res;
    }
};

(4.24)377. 组合总和 Ⅳ

class Solution {
vector<int>dp;
public:
    int combinationSum4(vector<int>& nums, int target) {
        int n=nums.size();
        dp.resize(target+1,0);
        dp[0]=1;
        for(int j=1;j<=target;j++)
        {
               for(int i=0;i<n;i++)
               {
                   if(j>=nums[i] && dp[j - nums[i]] < INT_MAX - dp[j])
                   dp[j]+=dp[j-nums[i]];
               }
         }
        return dp[target];

    }
};

(4.24)91. 解码方法

class Solution {
vector<int>dp;
public:
    int numDecodings(string s) {
       dp.resize(s.size()+1,0);
       dp[0]=1;
       if(s[0]!='0') dp[1]=1;
       else  return dp[1];
       for(int i=2;i<dp.size();i++)
       {
           if(s[i-1]!='0')
           {
               dp[i]+=dp[i-1];
           }
           if(s[i-2]!='0'&&0<s[i-1]-'0'+(s[i-2]-'0')*10&&s[i-1]-'0'+(s[i-2]-'0')*10<=26)
           {
               dp[i]+=dp[i-2];
           }
       }
       return dp[s.size()];
    }
};

(4.25)897. 递增顺序搜索树

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
private:
    stack<TreeNode*>q;
public:
    TreeNode* increasingBST(TreeNode* root) {
    TreeNode* anchor=new TreeNode(-1);
    TreeNode* cur=anchor;
    while(root||!q.empty())
    {
      while(root) 
      {
          q.push(root);
          root=root->left;
      }
       root=q.top();
         q.pop(); 
       cur->right=root;
       root->left=nullptr;//原因 没有把当前的左节点置为NULL
       cur=root;
       root=root->right;
    }
    return anchor->right;
    }
};

(4.28)633. 平方数之和

class Solution {
public:
    bool judgeSquareSum(int c) {
        int a=pow(double(c),0.5);
        for(int i=0;i<=a;i++)
        {
           int b = pow(c-i*i,0.5);
 
                if((i*i+b*b)==c) return true;
            
        }
        return false;
    }
};

(4.29)403. 青蛙过河

//dfs超时了
class Solution {
    set<int>m; int max;
    bool dfs(set<int>m,int i,int k)
    {
        if(i==max) return true;
        if(m.find(i)==m.end()) return false;
		else m.erase(i);
        return dfs(m,i+k,k)||dfs(m,i+k-1,k-1)||dfs(m,i+k+1,k+1);
    }
public:
    bool canCross(vector<int>& stones) {
       for(int i=0;i<stones.size();i++)
       {
           m.insert(stones[i]);
       }
       max=stones[stones.size()-1];
       return dfs(m,0,0);
    }
};
class Solution {
   bool dp[2000][2000];
public:
    bool canCross(vector<int>& stones) {
       memset(dp,false,sizeof(dp));
       if(stones[1]!=1) return false;
       dp[1][1]=true;
       int n=stones.size();
       for(int i=2;i<n;i++)
       {
           for(int j=1;j<i;j++)
           {
               int k=stones[i]-stones[j];
               if(k<=j+1)
               dp[i][k]=dp[j][k-1]||dp[j][k]||dp[j][k+1];
           }
       }
       for(int i = 1; i <n; i++){
            if(dp[n - 1][i]) return true;
        }   

       return false;
    }
};

(4.30)137. 只出现一次的数字 II

class Solution {
public:
    int singleNumber(vector<int>& nums) {
      int res=0;
      for(int i=0;i<32;i++)
      {
          int mask=1<<i;
          int tmp=0;
          for(int j=0;j<nums.size();j++)
          {
              if((mask&nums[j])!=0) tmp++;
          }
          if(tmp%3!=0) res|=mask;
      }
      return res;
    }
};

四月勋章达成:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值