(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;
}
};
四月勋章达成: