文章目录
-
重做题 402,403,404,407,413,414,415,416,417,418,421,424,426,432,435,436,437,438,439,440,442,443,445,446,448,449,450,451,454,455,458,459,460,461,462,464,465,466,467,468,470,471,472,473,474,475,476,477,478,479,480,481,482,486,487,488,489,490,491,493,494,495,
496
,497,498,499
-
401. 二进制手表(dfs)
-
402. 移掉K位数字(单调栈)
-
403. 青蛙过河
-
404. 左叶子之和
-
405. 数字转换为十六进制数
-
406. 根据身高重建队列
-
407. 接雨水 II
-
408. 有效单词缩写
-
409. 最长回文串
-
410. 分割数组的最大值
-
412. Fizz Buzz
-
413. 等差数列划分(dp)
-
414. 第三大的数
-
415. 字符串相加
-
416. 分割等和子集(背包问题)当成01背包问题
-
417. 太平洋大西洋水流问题
-
418. 屏幕可显示句子的数量
-
422. 有效的单词方块
-
423. 从英文中重建数字
-
424. 替换后的最长重复字符
-
426. 将二叉搜索树转化为排序的双向链表
-
-
433. 最小基因变化
-
434. 字符串中的单词数
-
435. 无重叠区间
-
436. 寻找右区间
-
437. 路径总和 III
-
438. 找到字符串中所有字母异位词
-
439. 三元表达式解析器
-
440. 字典序的第K小数字(十叉树)
-
441. 排列硬币
-
442. 数组中重复的数据
-
443. 压缩字符串
-
435. 无重叠区间(贪心)
-
445. 两数相加 II
-
446. 等差数列划分 II – 子序列
-
448. 找到所有数组中消失的数字(桶排序)
-
449. 序列化和反序列化二叉搜索树
-
450. 删除二叉搜索树中的节点
-
451. 根据字符出现频率排序(sort重写****************)
-
452. 用最少数量的箭引爆气球
-
453. 最小移动次数使数组元素相等
-
454. 四数相加 II(哈希取数**********)
-
455. 分发饼干
-
456. 132模式(单调栈)
-
458. 可怜的小猪
-
459. 重复的子字符串
-
460. LFU缓存
-
461. 汉明距离
-
462. 最少移动次数使数组元素相等 II(快速随机选择排序)
-
463. 岛屿的周长
-
464. 我能赢吗(位运算,哈希表在dfs中的使用)
-
465. 最优账单平衡
-
467. 环绕字符串中唯一的子字符串
-
468. 验证IP地址
-
470. 用 Rand7() 实现 Rand10()
-
472. 连接词
-
473. 火柴拼正方形
-
474. 一和零(背包)
-
475. 供暖器
-
476. 数字的补数
-
477. 汉明距离总和
-
478. 在圆内随机生成点
-
480. 滑动窗口中位数
-
481. 神奇字符串
-
482. 密钥格式化
-
487. 最大连续1的个数 II
-
488. 祖玛游戏
-
489. 扫地机器人
-
490. 迷宫
-
491. 递增子序列
-
493. 翻转对(树状数组)
-
494. 目标和
-
495. 提莫攻击
-
496. 下一个更大元素 I
-
498. 对角线遍历
-
499. 迷宫 III
重做题 402,403,404,407,413,414,415,416,417,418,421,424,426,432,435,436,437,438,439,440,442,443,445,446,448,449,450,451,454,455,458,459,460,461,462,464,465,466,467,468,470,471,472,473,474,475,476,477,478,479,480,481,482,486,487,488,489,490,491,493,494,495,
496
,497,498,499
401. 二进制手表(dfs)
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
void dfs(int p,int num)
{
if(path.size()==num)
{
res.push_back(path);
return;
}
if(p>=10)return;
path.push_back(p);
dfs(p+1,num);
path.pop_back();
dfs(p+1,num);
}
vector<string> readBinaryWatch(int num) {
dfs(0,num);
vector<string> vt;
unordered_map<int,int> mp = {{0,1},{1,2},{2,4},{3,8},{4,1},{5,2},{6,4},{7,8},{8,16},{9,32}};
for(auto&r:res)
{
int h = 0,m = 0;
for(auto&r1:r)
{
if(r1<=3)h += mp[r1];
else m += mp[r1];
}
if(h>=12 || m >= 60)continue;
string temp = "";
if(m<=9)temp = "0" + to_string(m);
else temp = to_string(m);
string v = to_string(h)+":"+temp;
vt.push_back(v);
}
return vt;
}
};
402. 移掉K位数字(单调栈)
class Solution {
public:
string removeKdigits(string num, int k) {
stack<char> st;
int len = num.size();
if(k>=len)return "0";
for(int i = 0;i<len;i++)
{
if(st.empty())st.push(num[i]);
else
{
if(st.size()==len-k && st.top()<=num[i])continue;
while(!st.empty() && st.top()>num[i] && st.size()+(len-i)>(len-k) )st.pop();
st.push(num[i]);
}
}
string res;
while(!st.empty())
{
res += st.top();st.pop();
}
reverse(res.begin(),res.end());
while(res.size()>1 && res[0]=='0')res = res.substr(1,res.size()-1);
return res;
}
};
经过思考,我理解了可以使用单调栈的思路:
比较a和b的大小,是从最高位开始进行比较的。
那么,我们也应该是从最高位开始进行删数。所以,就是对num进行单调上升栈的维护。
逐个数字入栈,当发现当前入栈元素<栈顶元素s.top()的时候,就s.pop(),维护栈的单调递增性。
这样就可以保证,结果的最高位最小,并以此递增。
TIPS:
当所有元素都进行过栈的处理之后,如果结果stack中的元素比要保留的长度要长的话,则把栈顶元素pop掉。
在入栈的时候,可忽略掉前置0.
作者:Smart_Shelly
链接:https://leetcode-cn.com/problems/remove-k-digits/solution/c-qing-xi-yi-dong-yi-ban-fang-fa-dan-diao-zhan-fan/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
string removeKdigits(string num, int k)
{
string result;
for (int i = 0; i < num.size(); i++)
{
while (result.size() && k&&result.back() > num[i])
{
result.pop_back();
k--;
}
if (result.size() == 0 && num[i] == '0')
continue;
result+=num[i];
}
while (k > 0 && !result.empty())
{
result.pop_back();
k--;
}
return result == "" ? "0" : result;
}
};
作者:Smart_Shelly
链接:https://leetcode-cn.com/problems/remove-k-digits/solution/c-qing-xi-yi-dong-yi-ban-fang-fa-dan-diao-zhan-fan/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
单调栈
string removeKdigits(string num, int k) {
stack<char> s;
for (int i = 0; i < num.size(); i++)
{
while (!s.empty() && s.top() > num[i] && k)
{
s.pop();
k--;
}
if (s.empty() && num[i] == '0')
continue;//跳过前置0
s.push(num[i]);
}
string result;
while (!s.empty())
{
if (k > 0)//当还要再移除数字的时候:从此时单调递增栈的top部删去数字
k--;
else if (k == 0)//当不用再移除数字的时候:把字符串取出来到result
result += s.top();
s.pop();
}
reverse(result.begin(), result.end());//stl中的reverse函数
return result == "" ? "0" : result;
}
作者:Smart_Shelly
链接:https://leetcode-cn.com/problems/remove-k-digits/solution/c-qing-xi-yi-dong-yi-ban-fang-fa-dan-diao-zhan-fan/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
dfs
class Solution {
public:
vector<string> res;
string path;
void dfs(int p,string num,int len,int k)
{
if(path.size()==len-k)
{
res.push_back(path);
return;
}
if(p>=len)return;
path.push_back(num[p]);
dfs(p+1,num,len,k);
path.pop_back();
dfs(p+1,num,len,k);
}
string removeKdigits(string num, int k) {
int len = num.size();
if(k>=len)return "0";
dfs(0,num,len,k);
int m = INT_MAX;
string r;
for(auto&s:res)
{
if(stoi(s)<m)
{
m = stoi(s);
r = s;
}
}
while(r.size()>1 && r[0]=='0')r = r.substr(1,r.size()-1);
return r;
}
};
403. 青蛙过河
class Solution {
public:
bool canCross(vector<int>& stones) {
if(stones[1]!=1)return false;
if(stones.size()==2)return true;
int len = stones.size();
unordered_map<int,int> mp;
for(int i = 0;i<len;i++)mp[stones[i]]=i;
vector<set<int>> dp(len);
dp[1].insert(1);
for(int i = 1;i<len;i++)
{
for(auto&j:dp[i])
{
if(mp.find(stones[i]+j-1)!=mp.end()){dp[mp[stones[i]+j-1]].insert(j-1);}
if(mp.find(stones[i]+j)!=mp.end()){dp[mp[stones[i]+j]].insert(j);}
if(mp.find(stones[i]+j+1)!=mp.end()){dp[mp[stones[i]+j+1]].insert(j+1);}
}
}
return !dp.back().empty();
}
};
404. 左叶子之和
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if(!root)return 0;
if(!root->left)return sumOfLeftLeaves(root->right);
if(!root->left->left && !root->left->right)return root->left->val + sumOfLeftLeaves(root->right);
return sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
};
405. 数字转换为十六进制数
class Solution {
public:
string toHex(int num) {
if(num==0)return "0";
unsigned int n = (unsigned int)num;
string res = "";
unordered_map<int,string> mp ={{10,"a"},{11,"b"},{12,"c"},{13,"d"},{14,"e"},{15,"f"}};
while(n)
{
auto t = n%16;
if(t<10)res = to_string(t)+res;
else res = mp[t] +res ;
n = n/16;
}
return res;
}
};
406. 根据身高重建队列
class Solution {
public:
static bool cmp(vector<int>a,vector<int>b)
{
if(a[0]==b[0])return a[1]<b[1];
return a[0]>b[0];
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(),people.end(),cmp);
vector<vector<int>> res;
for(auto&p:people)
{
res.insert(res.begin()+p[1],p);
}
return res;
}
};
407. 接雨水 II
思路:从边界最低处A出发,在A的四周,比A处还低的位置B一定能储水。
B的储水量 = A的高度-B的高度。并将B填充为新的边界。
如果A的周围没有比A低的,但是A处在边界无法储水。A的周围中最低的位置为新的边界。
如此,不断收缩储水区域的边界。
由于每次都要找出边界中最低的位置A。用优先级队列存储边界。
对位置A还要遍历其四周的位置。整个框架基于bfs。
作者:jason-2
链接:https://leetcode-cn.com/problems/trapping-rain-water-ii/solution/you-xian-ji-dui-lie-fa-by-jason-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Q<x,y,h>:优先级队列;
将地图的四周作为第一个边界,存入Q;
ans = 0;总储水量;
while(Q不空){
<x,y,h> = Q弹出堆顶;
for(<nx,ny> in <x,y>的上下左右){
if(<nx,ny> 在图上 且 在边界内部){
ans = ans + max(0,h - <nx,ny>的高度);
新边界位置<nx,ny,max(h,<nx,ny>的高度)>入Q;
}
}
}
作者:jason-2
链接:https://leetcode-cn.com/problems/trapping-rain-water-ii/solution/you-xian-ji-dui-lie-fa-by-jason-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
struct node{
int x,y,h;
node(int _x=0,int _y=0,int _h=0):x(_x),y(_y),h(_h){}
bool operator<(const node& o)const{
return h > o.h;
}
};
int R,C;
int trapRainWater(vector<vector<int>>& heightMap) {
if((R=heightMap.size())<3 || (C=heightMap[0].size())<3) return 0;
priority_queue<node> Q;
vector<vector<int>> vis(R,vector<int>(C,0));
//bottom and up line
for(int i=0;i<C;++i){
Q.push(node(0,i,heightMap[0][i]));
Q.push(node(R-1,i,heightMap[R-1][i]));
vis[0][i] = vis[R-1][i] = 1;
}
//left and right line
for(int i=0;i<R;++i){
Q.push(node(i,0,heightMap[i][0]));
Q.push(node(i,C-1,heightMap[i][C-1]));
vis[i][0] = vis[i][C-1] = 1;
}
const int dx[4] = {1,-1,0,0};
const int dy[4] = {0,0,1,-1};
int ans = 0;
while(Q.size()){
node cur = Q.top();Q.pop();
const int& x = cur.x;
const int& y = cur.y;
for(int i=0;i<4;++i){
const int nx = x + dx[i];
const int ny = y + dy[i];
if(in_grid(nx,ny) && !vis[nx][ny]){
vis[nx][ny] = 1;
int r=max(0,cur.h - heightMap[nx][ny]);
ans += r;
//(nx,ny)成为新边界的一部分,高度要更新
Q.push(node(nx,ny,max(cur.h,heightMap[nx][ny])));
}
}
}
return ans;
}
bool in_grid(int x,int y){
return x>=0 && x<R && y>=0 && y<C;
}
作者:jason-2
链接:https://leetcode-cn.com/problems/trapping-rain-water-ii/solution/you-xian-ji-dui-lie-fa-by-jason-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
408. 有效单词缩写
class Solution {
public:
bool validWordAbbreviation(string word, string abbr) {
int i = 0,j=0;
int len1 = word.size();
int len2 = abbr.size();
while(i<len1 && j<len2)
{
if(word[i]==abbr[j])
{
i++;j++;
}
else
{
if(isalpha(abbr[j]))return false;
else
{
int k = j;
while(j<len2 && isdigit(abbr[j]) )j++;
string t = abbr.substr(k,j-k);
if(t.size()>=1 && t[0]=='0')return false;
int temp = stoi(t);
i += temp;
}
}
}
if(i==len1 && j==len2)return true;
else return false;
}
};
409. 最长回文串
class Solution {
public:
int longestPalindrome(string s) {
unordered_map<char,int> mp;
for(auto&s1:s)mp[s1]++;
int res = 0;
bool b = false;
for(auto&m:mp)
{
int t = m.second;
if(t%2==0)res += t;
else {b=true;res += t-1;}
}
return b?res+1:res;
}
};
410. 分割数组的最大值
二分查找
int splitArray(vector<int>& nums, int m) {
long l = nums[0], h = 0;//int类型在这里不合适,因为h可能会超过int类型能表示的最大值
for (auto i : nums)
{
h += i;
l = l > i ? l : i;
}
while (l<h)
{
long mid = (l + h) / 2;
long temp = 0;
int cnt = 1;//初始值必须为1
for(auto i:nums)
{
temp += i;
if(temp>mid)
{
temp = i;
++cnt;
}
}
if(cnt>m)
l = mid + 1;
else
h = mid;
}
return l;
}
作者:coder233
链接:https://leetcode-cn.com/problems/split-array-largest-sum/solution/er-fen-cha-zhao-by-coder233-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
dfs超时
class Solution {
public:
vector<vector<int>> res;
vector<int> path = { 0 };
void dfs(int p, int len, int m)
{
if (path.size() == m)
{
res.push_back(path);
return;
}
if (p >= len)return;
path.push_back(p);
dfs(p + 1, len, m);
path.pop_back();
dfs(p + 1, len, m);
}
int func(vector<int> v)
{
int sum = 0;
for (auto v1 : v)sum += v1;
return sum;
}
int splitArray(vector<int> nums, int m) {
int len = nums.size();
dfs(1, len, m);
int c = INT_MAX;
for (auto&r : res)
{
r.push_back(len);
int m = 0;
for (int i = 0; i < r.size() - 1; i++)
{
vector<int> t(nums.begin() + r[i], nums.begin() + r[i + 1]);
m = max(m, func(t));
}
c = min(c, m);
}
return c;
}
};
412. Fizz Buzz
class Solution {
public:
vector<string> fizzBuzz(int n) {
vector<string> res;
for(int i = 1;i<=n;i++)
{
if(i%3==0 && i%5==0)res.push_back("FizzBuzz");
else if(i%3==0)res.push_back("Fizz");
else if(i%5==0)res.push_back("Buzz");
else res.push_back(to_string(i));
}
return res;
}
};
413. 等差数列划分(dp)
注意时子数组不是子序列
如果前面三个是等差的,那么新加入的这个会增加前面加1个,最后将所有数组相加,直接硬写出总和的dp是有难度的
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& A) {
// 求的是子区间而不是子序列构成的区间,这样只需要计算每次新加入的对之前的影响就行
int len = A.size();
vector<int> dp(len,0);
for(int i = 2; i<len ;i++)
{
if(A[i]-A[i-1]==A[i-1]-A[i-2])
{dp[i] = dp[i-1] +1;}
}
int sum = 0;
for(auto i:dp){sum +=i;}
return sum;
}
};
414. 第三大的数
与那种必须要求递增为3的做法区别开
int thirdMax(vector<int>& nums) {
vector<int> ans;
for (auto n : nums) {
bool bSame = false;
for (auto a : ans) {
if (n == a) {
bSame = true;
break;
}
}
if (bSame) continue;
for (int i = 0; i < ans.size(); i++) { //核心在这里,上面的会被交换下去
if (n > ans[i]) {
swap(n, ans[i]);
}
}
if (ans.size() < 3) {
ans.push_back(n);
}
}
if (ans.empty()) return 0;
if (ans.size() < 3) return ans.front();
return ans.back();
}
作者:ikaruga
链接:https://leetcode-cn.com/problems/third-maximum-number/solution/third-maximum-number-by-ikaruga/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
应该可以看成n的
class Solution {
public:
int thirdMax(vector<int>& nums) {
priority_queue<int,vector<int>,greater<int>>qt;
unordered_set<int> st;
for(auto&n:nums)
{
if(st.find(n)==st.end())
{
if(qt.size()<3)qt.push(n);
else if(qt.top()<n)
{
qt.push(n);qt.pop();
}
st.insert(n);
}
}
if(qt.size()==3)return qt.top();
else
{
while(qt.size()>1 )qt.pop();
return qt.top();
}
}
};
415. 字符串相加
class Solution {
public:
string addStrings(string num1, string num2) {
string t ;
int sum = 0, i = num1.size()-1, j = num2.size()-1;
while(i >= 0 || j >= 0 || sum)
{
if(i >= 0) sum += num1[i--] - '0';
if(j >= 0) sum += num2[j--] - '0';
t.push_back(sum%10 + '0');
sum /= 10;
}
reverse(t.begin(),t.end());
return t;
}
};
作者:zrita
链接:https://leetcode-cn.com/problems/add-strings/solution/c-z-by-zrita-23/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
string addStrings(string num1, string num2) {
int len1 = num1.size();
int len2 = num2.size();
int len = max(len1, len2);
while (len1 < len2)
{
num1 = "0" + num1; len1++;
}
while (len2 < len1)
{
num2 = "0" + num2; len2++;
}
while (1)
{
string jinwei(num1.size(), ' ');
string he(num1.size(), ' ');
for (int i = 0; i < num1.size(); i++)
{
int t = (int)(num1[i] - '0') + (int)(num2[i] - '0');
if (t <= 9)
{
he[i] = (char)(t + '0');
jinwei[i] = '0';
}
else
{
jinwei[i] = (char)(t/10 + '0');
he[i] = (char)(t%10 + '0');
}
}
num1 = "0" + he;
num2 = jinwei + "0";
bool b = false;
for (auto&c : jinwei)
{
if (c != '0')
{
b = true;
break;
}
}
if (!b)break;
}
while (num1.size()>1 && num1[0] == '0')num1 = num1.substr(1, num1.size() - 1);
return num1;
}
};
416. 分割等和子集(背包问题)当成01背包问题
class Solution {
public:
bool canPartition(vector<int>& nums) {
//背包问题
int sum = 0;
for(auto&n:nums)sum += n;
if(sum%2!=0)return false;
int len = nums.size();
vector<vector<int>> dp(len+1,vector<int>(sum/2+1,0));
for(int i = 1;i<=len;i++)
{
for(int j =1;j<=sum/2;j++)
{
if(j<nums[i-1])dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1]);
}
}
return dp[len][sum/2]==sum/2;
}
};
417. 太平洋大西洋水流问题
dfs
class Solution {
public:
vector<int> path;
vector<vector<int>> visited;
void dfs(int i, int j,vector<vector<int>> matrix,int m,int n)
{
bool b = false;
if(i==0 || j==0)
{
path[0]=1;b = true;
}
if(i==m-1 || j==n-1)
{
path[1]=1; b=true;
}
//if(b)return;
visited[i][j]=1;
if(i+1<m && visited[i+1][j]==0 && matrix[i+1][j]<=matrix[i][j])dfs(i+1,j,matrix,m,n);
if(j+1<n && visited[i][j+1]==0 && matrix[i][j+1]<=matrix[i][j])dfs(i,j+1,matrix,m,n);
if(i-1>=0 && visited[i-1][j]==0 && matrix[i-1][j]<=matrix[i][j])dfs(i-1,j,matrix,m,n);
if(j-1>=0 && visited[i][j-1]==0 && matrix[i][j-1]<=matrix[i][j])dfs(i,j-1,matrix,m,n);
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
if(matrix.empty())return {};
int m = matrix.size();
int n = matrix[0].size();
vector<vector<int>> res;
for(int i =0;i<m;i++)
{
for(int j = 0;j<n;j++)
{
path = vector<int>(2,0);
visited = vector<vector<int>>(m,vector<int>(n,0));
dfs(i,j,matrix,m,n);
if(path[0]==1 && path[1]==1)res.push_back({i,j});
}
}
return res;
}
};
418. 屏幕可显示句子的数量
class Solution {
public:
int wordsTyping(vector<string> sentence, int rows, int cols) {
int len = sentence.size();
int i = 0, j = 0;//放置单词的具体位置
int n = 0;//单词的序号
int count = 0;
while (i < rows)
{
if (j + sentence[n].size() <= cols)
{
j += sentence[n++].size();
if (j == cols || j == cols - 1) { i++; j = 0; }
else j++;
}
else
{
i++; j = 0;
}
if (n == len )
{
count++;
n = 0;
}
}
return count;
}
};
422. 有效的单词方块
class Solution {
public:
bool validWordSquare(vector<string>& words) {
int len = words.size();
for(int i = 0;i<len;i++)
{
string temp = "";
for(int j = 0;j<len;j++)
{
if(words[j].size()>i)
{
temp += words[j][i];
}
}
if(temp!=words[i])return false;
}
return true;
}
};
423. 从英文中重建数字
class Solution {
public:
string path;
string res;
unordered_map<char, int> mp1;
void dfs(int p, vector<string> vt)
{
if (mp1.empty())
{
res = path;
return;
}
if (p >= vt.size())return;
bool b = true;
for (auto&v : vt[p])
{
if (mp1.find(v) == mp1.end()) { b = false; break; }
}
if (b)
{
for (auto&v : vt[p])
{
mp1[v]--;
if (mp1[v] == 0)mp1.erase(v);
}
path += (char)(p+'0');
dfs(p, vt);
path.pop_back();
for (auto&v : vt[p])
{
mp1[v]++;
}
}
dfs(p + 1, vt);
}
string originalDigits(string s) {
unordered_map<char, int> mp;
for (auto&s1 : s)mp[s1]++;
vector<string> vt = { "zero","one","two","three","four","five","six","seven","eight","nine" };
mp1 = mp;
dfs(0, vt);
sort(res.begin(), res.end());
return res;
}
};
424. 替换后的最长重复字符
class Solution {
public:
int characterReplacement(string s, int k) {
int count[26]={0};//建立字符->字符数量的映射
int left=0,right=0,result=0,maxCount=0;
while(right<s.size())
{
count[s[right]-'A']++;
maxCount=max(maxCount,count[s[right]-'A']);//当前窗口内的最多字符的个数
if(right-left+1-maxCount>k){//需要替换的字符个数就是当前窗口的大小减去窗口中数量最多的字符的数量
count[s[left]-'A']--;//缩小窗口
left++;
}
//当窗口内可替换的字符数小于等于k时,我们需要根据该窗口长度来确定是否更新result
result=max(result,right-left+1);
right++;
}
return result;
}
};
作者:xiaoneng
链接:https://leetcode-cn.com/problems/longest-repeating-character-replacement/solution/hua-dong-chuang-kou-chang-gui-tao-lu-by-xiaoneng/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
426. 将二叉搜索树转化为排序的双向链表
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
Node* temp;
void dfs(Node* root)
{
if(!root)return;
dfs(root->left);
temp->right = root;
root->left = temp;
temp = root;
dfs(root->right);
}
Node* treeToDoublyList(Node* root) {
Node* head1 = new Node(0);
head1->right = root;
temp = head1;
dfs(root);
temp->right = head1->right;
head1->right->left = temp;
return head1->right;
}
};
class AllOne {
public:
list<pair<string, int>> m_list;
unordered_map<string, list<pair<string, int>>::iterator> m_map;
/** Initialize your data structure here. */
AllOne() {
}
/** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
void inc(string key) {
if (m_map.count(key) == 0) {
m_list.push_back({key, 1});
m_map[key] = prev(m_list.end());
return;
}
auto it = m_map[key];
++(it->second);
auto pit = prev(it);
while (it != m_list.begin() && it->second > pit->second) {
iter_swap(it, pit);
m_map[it->first] = it;
m_map[pit->first] = pit;
pit = prev(pit);
it = prev(it);
}
}
/** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
void dec(string key) {
if (m_map.count(key) == 0) {
return;
}
auto it = m_map[key];
--(it->second);
if (it->second == 0) {
m_list.erase(it);
m_map.erase(key);
return;
}
auto nit = next(it);
while (nit != m_list.end() && nit->second > it->second) {
iter_swap(it, nit);
m_map[it->first] = it;
m_map[nit->first] = nit;
nit = next(nit);
it = next(it);
}
}
/** Returns one of the keys with maximal value. */
string getMaxKey() {
if (m_list.empty()) {
return "";
}
return m_list.begin()->first;
}
/** Returns one of the keys with Minimal value. */
string getMinKey() {
if (m_list.empty()) {
return "";
}
return prev(m_list.end())->first;
}
};
/**
* Your AllOne object will be instantiated and called as such:
* AllOne* obj = new AllOne();
* obj->inc(key);
* obj->dec(key);
* string param_3 = obj->getMaxKey();
* string param_4 = obj->getMinKey();
*/
作者:chennxi
链接:https://leetcode-cn.com/problems/all-oone-data-structure/solution/c-map-list-by-chennxi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
433. 最小基因变化
class Solution {
public:
int isok(string a, string b)
{
int count = 0;
for(int i = 0;i<a.size();i++)
{
if(a[i]!=b[i])count++;
}
return count;
}
int minMutation(string start, string end, vector<string>& bank) {
int len = bank.size();
vector<int>visited(len,0);
queue<string> qt;
qt.push(start);
int res =0;
while(!qt.empty())
{
int l = qt.size();
for(int i = 0;i<l;i++)
{
auto t = qt.front();
qt.pop();
if(t==end)
{
return res;
}
for(int i = 0;i<len;i++)
{
if(visited[i]==0 && isok(t,bank[i])==1)
{
visited[i]=1;
qt.push(bank[i]);
}
}
}
res++;
}
return -1;
}
};
434. 字符串中的单词数
class Solution {
public:
int countSegments(string s) {
int res = 0;
int i = 0;
int len = s.size();
while(i<len)
{
while(i<len && s[i]==' ')i++;
int j = i;
while(i<len && s[i]!=' ')i++;
if(j!=i)res++;
}
return res;
}
};
435. 无重叠区间
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
vector<vector<int>> res;
if(intervals.empty())return 0;
sort(intervals.begin(),intervals.end());
res.push_back(intervals[0]);
for(int i = 1;i<intervals.size();i++)
{
if(intervals[i][0]>=res.back()[1])
{
res.push_back(intervals[i]);
}
else
{
res.back()[1] = min(res.back()[1],intervals[i][1]);
}
}
return intervals.size()-res.size();
}
};
436. 寻找右区间
class Solution {
public:
static bool cmp(vector<int>a, vector<int>b)
{
if (a[0] == b[0])return a[1] > b[1];
return a[0] < b[0];
}
int func(int target, vector<vector<int>>vt)
{
int res = 0;
int left = 0, right = vt.size();
while (left < right)
{
int mid = left + (right - left) / 2;
if (vt[mid][0] < target)left = mid + 1;
else right = mid;
}
return left==vt.size()?-1:vt[left][1];
}
vector<int> findRightInterval(vector<vector<int>> intervals) {
if (intervals.empty())return {};
vector<vector<int>> vt;
int len = intervals.size();
for (int i = 0; i < len; i++)
{
vt.push_back({ intervals[i][0],i });
}
sort(vt.begin(), vt.end(), cmp);
vector<int> res;
for (int i = 0; i < len; i++)
{
int t = intervals[i][1];
res.push_back(func(t, vt));
}
return res;
}
};
437. 路径总和 III
这三句话的顺序特别重要,3必须放在2之后,因为必须把当前节点加上才有意义
class Solution {
public:
int res = 0;
void dfs(TreeNode* root,int sum,int taregt)
{
if(!root)return;//1
sum += root->val;//2
if(sum==taregt)res++;//3
dfs(root->left,sum,taregt);
dfs(root->right,sum,taregt);
sum -= root->val;
}
void dfs1(TreeNode* root,int sum)
{
if(!root)return ;
dfs(root,0,sum);
dfs1(root->left,sum);
dfs1(root->right,sum);
}
int pathSum(TreeNode* root, int sum) {
if(!root)return 0;
dfs1(root,sum);
return res;
}
};
438. 找到字符串中所有字母异位词
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
if(s.size()<p.size() || s.empty() || p.empty())return {};
unordered_map<char, int> mp;
int lens = s.size();
int lenp = p.size();
for (auto&p1 : p)mp[p1]++;
int start = 0, end = 0;
vector<int> res;
unordered_map<char, int> win;
win[s[0]]++;
while (end < s.size() - 1)
{
if (end - start + 1 < lenp)
{
end++;
win[s[end]]++;
}
else if (end - start + 1 == lenp)
{
if (mp == win)res.push_back(start);
win[s[start]]--;
if (win[s[start]] == 0)win.erase(s[start]);
start++;
end++;
win[s[end]]++;
//if (mp == win)res.push_back(start);
}
}
if (mp == win)res.push_back(start);
return res;
}
};
439. 三元表达式解析器
将 ? 看做 ( ,将 : 看做 ),就将”A?B:C”化归为括号匹配问题”A(B)C”。括号匹配可以用栈,但实际不需要创建栈,只需要用一个整数stk储存当前未匹配的左括号数量。若第一个字符为T则取两个括号之间的表达式值B,否则取括号后面的表达式值C。子表达式B、C仍有可能是三元表达式,递归求其值即可。递归终止条件为表达式只剩一个字符。
作者:
TreeDiagram
链接:https://leetcode-cn.com/problems/ternary-expression-parser/solution/cjian-ji-shuang-bai-by-
treediagram
/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
string parseTernary(string expression) {
if(expression.size()==1){
return expression;
}
else{
int stk=1,i=2;
while(stk!=0){
++i;
if(expression[i]=='?') ++stk;
else if(expression[i]==':') --stk;
}
if(expression[0]=='T'){
return parseTernary(expression.substr(2,i-2));
}
else{
return parseTernary(expression.substr(i+1));
}
}
}
};
作者:__TreeDiagram__
链接:https://leetcode-cn.com/problems/ternary-expression-parser/solution/cjian-ji-shuang-bai-by-__treediagram__/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
用栈从后往前,遇到数字放进栈里。 遇到T就保留栈顶的,删掉第二个。 遇到F就删除栈顶的,保留第二个。
string parseTernary(string &expression) {
// write your code here
char stk[5000];
int top = 0;
int len = expression.length();
for(int i = len - 1; i >= 0; i--) {
if(expression[i] == '?') {
i--, top--;
if(expression[i] == 'T')
stk[top - 1] = stk[top];
}
else if(expression[i] != ':'){
stk[top++] = expression[i];
}
}
string t;
t += stk[0];
return t;
}
440. 字典序的第K小数字(十叉树)
这道题是之前那道Lexicographical Numbers的延伸,之前让按字典顺序打印数组,而这道题让我们快速定位某一个位置,那么我们就不能像之前那道题一样,一个一个的遍历,这样无法通过OJ,这也是这道题被定为Hard的原因。那么我们得找出能够快速定位的方法,我们如果仔细观察字典顺序的数组,我们可以发现,其实这是个十叉树Denary Tree,就是每个节点的子节点可以有十个,比如数字1的子节点就是10到19,数字10的子节点可以是100到109,但是由于n大小的限制,构成的并不是一个满十叉树。我们分析题目中给的例子可以知道,数字1的子节点有4个(10,11,12,13),而后面的数字2到9都没有子节点,那么这道题实际上就变成了一个先序遍历十叉树的问题,那么难点就变成了如何计算出每个节点的子节点的个数,我们不停的用k减去子节点的个数,当k减到0的时候,当前位置的数字即为所求。现在我们来看如何求子节点个数,比如数字1和数字2,我们要求按字典遍历顺序从1到2需要经过多少个数字,首先把1本身这一个数字加到step中,然后我们把范围扩大十倍,范围变成10到20之前,但是由于我们要考虑n的大小,由于n为13,所以只有4个子节点,这样我们就知道从数字1遍历到数字2需要经过5个数字,然后我们看step是否小于等于k,如果是,我们cur自增1,k减去step;如果不是,说明要求的数字在子节点中,我们此时cur乘以10,k自减1,以此类推,直到k为0推出循环,此时cur即为所求:
class Solution {
public:
int findKthNumber(int n, int k) {
int cur = 1;
--k;
while (k > 0) {
long long step = 0, first = cur, last = cur + 1;
while (first <= n) {
step += min((long long)n + 1, last) - first;
first *= 10;
last *= 10;
}
if (step <= k) {
++cur;
k -= step;
} else {
cur *= 10;
--k;
}
}
return cur;
}
};
441. 排列硬币
class Solution {
public:
int arrangeCoins(int n) {
int sum = n;
if(n==1)return 1;
int i = 1;
for( i = 1;i<n;i++)
{
sum -= i;
if(sum<0)break;
}
return i-1;
}
};
442. 数组中重复的数据
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
vector<int> vt;
for(auto&n:nums)
{
if(nums[abs(n)-1]>0)nums[abs(n)-1]=-nums[abs(n)-1];
else
{
vt.push_back(abs(n));
}
}
return vt;
}
};
443. 压缩字符串
class Solution {
public:
int compress(vector<char>& chars) {
int i =0;
int j = 0;
while(i<chars.size())
{
int k = i;
while(i<chars.size() && chars[i]==chars[k])i++;
if(i-k>1)
{
string t = to_string(i-k);
chars[j++]=chars[k];
for(auto&t1:t)
{
chars[j++]=t1;
}
}
else
{
chars[j++] = chars[k];
}
}
return j;
}
};
435. 无重叠区间(贪心)
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) return 0;
sort(intervals.begin(), intervals.end());
int left = intervals[0][1];
int res = 0;
for (int i = 1; i < intervals.size(); ++i) {
if (intervals[i][0] < left) {
++res;
left = min(left, intervals[i][1]);
} else {
left = intervals[i][1];
}
}
return res;
}
};
作者:da-li-wang
链接:https://leetcode-cn.com/problems/non-overlapping-intervals/solution/c-pai-xu-hou-tan-xin-fa-ti-jie-by-da-li-wang/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
//sort()必须时静态成员函数
static bool cmp(vector<int>a,vector<int>b){
return a[1]<b[1];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) return 0;
//按照区间终结点,从小到大排序
sort(intervals.begin(), intervals.end(),cmp);
//获取最小的,区间终结点
int end = intervals[0][1];
int res = 0;
for (int i = 1; i < intervals.size(); ++i) {
//如果区间的起点,小于上一个区间的终点,说明有交集,要删除
if (intervals[i][0] < end) {
++res;
} else {
//没有交集,更新end
end = intervals[i][1];
}
}
return res;
}
};
作者:liu-wen-tao-2
链接:https://leetcode-cn.com/problems/non-overlapping-intervals/solution/ctan-xin-suan-fa-by-liu-wen-tao-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
445. 两数相加 II
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
stack<ListNode*> s1;
stack<ListNode*> s2;
while(l1){s1.push(l1);l1 = l1->next;}
while(l2){s2.push(l2);l2 = l2->next;}
int b = 0;
auto head= new ListNode(0);
while(!s1.empty() && !s2.empty())
{
int x = s1.top()->val+s2.top()->val; s1.pop(); s2.pop();
auto temp = new ListNode((x+b)%10);
temp->next = head->next;
head->next = temp;
b = ((x+b)>=10)?1:0;
}
while(!s1.empty())
{
int x = s1.top()->val; s1.pop();
auto temp = new ListNode((x+b)%10);
temp->next = head->next;
head->next = temp;
b = ((x+b)>=10)?1:0;
}
while(!s2.empty())
{
int x = s2.top()->val; s2.pop();
auto temp = new ListNode((x+b)%10);
temp->next = head->next;
head->next = temp;
b = ((x+b)>=10)?1:0;
}
if(b)
{
head->val=1;return head;
}
else
{
auto head1 = head->next;
delete head;
return head1;
}
}
};
446. 等差数列划分 II – 子序列
class Solution {
public:
int numberOfArithmeticSlices(vector<int>& A) {
int len = A.size();
vector<unordered_map<int,int>> dp(len);
int res = 0;
for(int i = 1;i<len;i++)
{
for(int j = 0;j<i;j++)
{
auto t = A[i]-A[j];
if(dp[j].find(t)==dp[j].end())
{
dp[i][t] += 1;
}
else
{
dp[i][t] += dp[j][t] + 1 ;
res += dp[j][t];
}
}
}
return res;
}
};
448. 找到所有数组中消失的数字(桶排序)
class Solution {
public:
vector<int> findDisappearedNumbers(vector<int>& nums) {
for(auto&n:nums)
{
if(nums[abs(n)-1]>0)nums[abs(n)-1]=0-nums[abs(n)-1];
}
vector<int> res;
for(int i = 0;i<nums.size();i++)
{
if(nums[i]>0)res.push_back(i+1);
}
return res;
}
};
449. 序列化和反序列化二叉搜索树
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
string s;
// Encodes a tree to a single string.
void dfs(TreeNode* root)
{
if(!root)return;
s += to_string(root->val) + ",";
dfs(root->left);
dfs(root->right);
}
string serialize(TreeNode* root) {
dfs(root);
return s;
}
TreeNode* func(vector<int>& pre, vector<int>& ior)
{
if(pre.empty())return NULL;
int t = find(ior.begin(),ior.end(),pre[0])-ior.begin();
vector<int> preleft(pre.begin()+1,pre.begin()+1+t);
vector<int> preright(pre.begin()+1+t,pre.end());
vector<int> iorleft(ior.begin(),ior.begin()+t);
vector<int> iorright(ior.begin()+t+1,ior.end());
auto root = new TreeNode(pre[0]);
root->left = func(preleft,iorleft);
root->right = func(preright,iorright);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
vector<int> st;
int i = 0;
while(i<data.size())
{
int j = i;
while(i<data.size() && data[i]!=',')i++;
if(j==i || i==data.size())break;
st.push_back(stoi(data.substr(j,i-j)));
i++;
}
auto vt1 = st;
sort(vt1.begin(),vt1.end());
return func(st,vt1);
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
450. 删除二叉搜索树中的节点
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root) return NULL;
if(key < root -> val){ // 找到key所在的位置
root -> left = deleteNode(root -> left, key);
return root;
}
if(key > root -> val){ // 找到key所在的位置
root -> right = deleteNode(root -> right, key);
return root;
}
// 当key == root -> val, 即找到目标点时
//当目标点只有一边子树时
if(!root -> left){ // 若没有左子树,删除目标点,右子树接上
TreeNode* temp = root -> right;
delete(root);
return temp;
}
if(!root -> right){ // 若没有右子树,删除目标点,左子树接上
TreeNode* temp = root -> left;
delete(root);
return temp;
}
//当目标点左右都有子树时
TreeNode* temp = root -> right; // 找到右子树中最小的值,即进入右子树后一直向左遍历
while(temp -> left) temp = temp -> left;
swap(root -> val, temp -> val); // 交换值
root -> right = deleteNode(root -> right, key); // 进入遍历,删除key
return root;
}
};
作者:youlookdeliciousc
链接:https://leetcode-cn.com/problems/delete-node-in-a-bst/solution/cdi-gui-si-lu-xiang-xi-zhu-shi-by-youlookdelicious/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
451. 根据字符出现频率排序(sort重写****************)
这道题是一道典型的sort重写题:
1.如果要对哈希表写排序,还是最好先将整个pair
放到向量中进行排序
,对于pai取值要使用。来取值,什么时候用-》需要再留意
2.重写func函数时记住函数的参数是要比较的元素的引用,而且整个函数要设置为一个静态函数类型
static bool value_compare(const pair<char, int>& p1, const pair<char, int>& p2)
{
return p1.second > p2.second;
}
string frequencySort(string s) {
map<char, int> m;
for(int i = 0;i < s.size(); ++i)
{
++m[s.at(i)];
}
vector<pair<char, int>> v(m.begin(), m.end());
sort(v.begin(), v.end(), value_compare);
string s1;
s1.reserve(s.capacity());
for(int i = 0; i < v.size(); ++i)
{
for(int j = 0; j < v.at(i).second; ++j)
s1.push_back(v.at(i).first);
}
return s1;
}
template<typename T, typename U>
struct value_less
{
bool operator()(const pair<T, U>& left, const pair<T, U>& right) const
{
return left.second < right.second;
}
};
//2.1、map + 最大堆
string frequencySort(string s) {
map<char, int> m;
for (int i = 0; i < s.size(); ++i)
{
++m[s.at(i)];
}
priority_queue<pair<int, char>> queue; //使用默认的pair operator<() 比较 也满足题意
for (auto iter = m.begin(); iter != m.end(); ++iter)
{
queue.push(pair<int, char>(iter->second, iter->first));
}
string s1;
s1.reserve(s.capacity());
while (!queue.empty())
{
for (int i = 0; i < queue.top().first; ++i)
{
s1.push_back(queue.top().second);
}
queue.pop();
}
return s1;
}
作者:eric-345
链接:https://leetcode-cn.com/problems/sort-characters-by-frequency/solution/c-san-chong-fang-fa-by-eric-345-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
还可以直接对字符串进行排序,然后排序的时候利用哈希表
class Solution {
public:
string frequencySort(string s) {
unordered_map<char, int> hash;
for(auto ch : s) hash[ch]++;
sort(s.begin(), s.end(), [&](char& a, char& b){
return hash[a] > hash[b] || (hash[a] == hash[b] && a < b);
});
return s;
}
};
452. 用最少数量的箭引爆气球
好像最大最小没有区别,值得注意的仅仅是边界重合问题
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if(points.empty())return 0;
sort(points.begin(),points.end());
int dp = points[0][1], res = 0;
for(int i =1 ;i<(int)points.size() ;i++)
{
if(points[i][0]<=dp)
{res++;dp=min(dp,points[i][1]);}
else {dp=points[i][1];}
}
return (int)points.size()-res;
}
};
453. 最小移动次数使数组元素相等
class Solution {
public:
int minMoves(vector<int>& nums) {
int m = *min_element(nums.begin(),nums.end());
int sum = 0;
for(auto&n:nums)sum += n-m;
return sum;
}
};
454. 四数相加 II(哈希取数**********)
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int res = 0;
unordered_map<int,int> mp;
for(auto&i:A)
{
for(auto&j:B)
{
mp[i+j]++;
}
}
for(auto&i:C)
{
for(auto&j:D)
{
res += mp[0-i-j];
}
}
return res;
}
};
class Solution {
public:
int res = 0;
vector<int> vt;
unordered_map<string, int> mp;
void dfs(vector<vector<int>>board,int m, int n,int target)
{
//判断越界
bool b = false;
for (auto&v : vt)
{
if (v == n) { b = true; break; }
}
if (b)return;
//判断重复
string key;
for (auto&v : vt)
{
key += to_string(v);
}
if (mp[key] > 0)return;
//判断是否符合要求
int sum = 0;
for (int i = 0;i<m;i++)
{
sum += board[i][vt[i]];
}
if (sum == target)res++;
mp[key]++;
for (int i = 0; i < m; i++)
{
vt[i]++;
dfs(board,m,n,target);
vt[i]--;
}
}
int fourSumCount(vector<int> A, vector<int> B, vector<int> C,vector<int> D) {
vector<vector<int>> board = {A,B,C,D};
int m = board.size();
int n = board[0].size();
vt = vector<int>(m,0);
dfs(board,m,n,0);
return res;
}
};
用了两个哈希表分别记录AB和CD的两两之和出现次数,然后遍历其中一个哈希表,并在另一个哈希表中找和的相反数出现的次数。
class Solution {
public:
int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
int n = A.size(), res = 0;
unordered_map<int, int>hash1, hash2;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
hash1[A[i] + B[j]]++;
hash2[C[i] + D[j]]++;
}
}
for(auto m : hash1) res += m.second * (hash2[-m.first]);
return res;
}
};
之前一直不懂。和-》取数的区别,下面是几点说明1.对哈希遍历可以不适用迭代器,而直接使用auto这样出来的其实是一个pair类型,对于这种类型采用点取值2,如果采用迭代器迭代的方式,得到的是迭代器,迭代器在这时取值采用的是-》符号,如果是向量中的迭代器取值采用的是&
/*
for(auto iter = mp1.begin();iter!=mp1.end();iter++)
{
res += mp2[-iter->first]*iter->second;
}
*/
455. 分发饼干
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int res= 0 ;
int i = 0;
int j = 0;
while(i<g.size() && j<s.size())
{
if(g[i]<=s[j])
{
i++;j++;
res++;
}
else
{
while(j<s.size() && s[j]<g[i])j++;
}
}
return res;
}
};
456. 132模式(单调栈)
class Solution {
public:
bool find132pattern(vector<int>& nums) {
int n = nums.size();
vector<int> each_min;
for(auto& m : nums){
if(each_min.empty()) each_min.push_back(m);
each_min.push_back(min(m,each_min.back()));
}
stack<int> s;
for(int i=n-1;i>=0;--i){
while(!s.empty() && s.top() < nums[i]){
if(s.top() > each_min[i]) return true;
else s.pop();
}
s.push(nums[i]);
}
return false;
}
};
作者:nuo-_yan
链接:https://leetcode-cn.com/problems/132-pattern/solution/dan-diao-di-jian-zhan-by-nuo-_yan/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
458. 可怜的小猪
class Solution {
public:
int poorPigs(int buckets, int minutesToDie, int minutesToTest) {
int sta=minutesToTest/minutesToDie+1;
return ceil(log(buckets)/log(sta));
}
};
作者:tengyun-3
链接:https://leetcode-cn.com/problems/poor-pigs/solution/da-bai-hua-jie-shi-by-tengyun-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
459. 重复的子字符串
如果您的字符串S包含一个重复的子字符串,那么这意味着您可以多次“移位和换行”您的字符串,并使其与原始字符串匹配。
例如:abcabc
移位一次:cabcab
移位两次:bcabca
移位三次:abcabc
现在字符串和原字符串匹配了,所以可以得出结论存在重复的子串
基于这个思想,可以每次移动k个字符,直到匹配移动length – 1次。但是这样对于重复字符串很长的字符串,效率会非常低。在LeetCode中执行时间超时了。
为了避免这种无用的环绕,可以创建一个新的字符串str,它等于原来的字符串S再加上S自身,这样其实就包含了所有移动的字符串。
比如字符串:S = acd,那么str = S + S = acdacd
acd移动的可能:dac、cda。其实都包含在了str中了。就像一个滑动窗口
一开始acd (acd) ,移动一次ac(dac)d,移动两次a(cda)cd。循环结束
所以可以直接判断str中去除首尾元素之后,是否包含自身元素。如果包含。则表明存在重复子串。
作者:13217319563
链接:https://leetcode-cn.com/problems/repeated-substring-pattern/solution/jian-dan-ming-liao-guan-yu-javaliang-xing-dai-ma-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思路大致如下:如果一个非空字符串s可以由它的一个子串重复多次构成,可以理解为s中存在m个子串,那么当两个字符串结合起来变成ss时,字符串s在新字符串ss的第二次位置不等于s的长度(相当于前一个字符串s中有n个子串,在后一个字符串中有m-n个子串,所以此时的位置不等于s的长度);反之,一个非空字符串s不可以由它的一个子串重复多次构成,那么当两个字符串结合起来变成ss时,字符串s在新字符串ss的第二次位置就在后一个字符串首字符的位置,其位置刚好等于s的长度。根据这一特征来判断。
作者:lo_e
链接:https://leetcode-cn.com/problems/repeated-substring-pattern/solution/c-findhan-shu-yong-fa-by-lo_e/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
string str1, str2;
str1.find(str2); //从串str1中查找时str2,返回str2中首个字符在str1中的地址
str1.find(str2,5); //从str1的第5个字符开始查找str2
作者:lo_e
链接:https://leetcode-cn.com/problems/repeated-substring-pattern/solution/c-findhan-shu-yong-fa-by-lo_e/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
bool repeatedSubstringPattern(string s) {
return (s+s).find(s,1)!=s.size();
}
};
作者:lo_e
链接:https://leetcode-cn.com/problems/repeated-substring-pattern/solution/c-findhan-shu-yong-fa-by-lo_e/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
460. LFU缓存
461. 汉明距离
class Solution {
public:
int hammingDistance(int x, int y) {
int z = x^y;
int count = 0;
while(z)
{
count++;
z = z &(z-1);
}
return count;
}
};
462. 最少移动次数使数组元素相等 II(快速随机选择排序)
class Solution {
public:
int func(vector<int>& nums,int left,int right)
{
int i = left;
int j = right;
while(i<j)
{
while(i<j && nums[j]>=nums[left])j--;
while(i<j && nums[i]<= nums[left])i++;
if(i<j)swap(nums[i],nums[j]);
}
swap(nums[left],nums[i]);
return i;
}
int select(vector<int>& nums,int left, int right, int mid)
{
int t =func(nums,left,right);
if(t==mid)return nums[t];
else if(t<mid)return select(nums,t+1,right,mid);
else return select(nums,left,t-1,mid);
}
int minMoves2(vector<int>& nums) {
int m = select(nums,0,nums.size()-1,(nums.size())/2);
int res = 0;
for(auto&n:nums)
{
res += abs(n-m);
}
return res;
}
};
463. 岛屿的周长
class Solution {
public:
int func(vector<vector<int>>& grid,int m,int n,int x,int y)
{
int c = 0;
if(x+1<m && grid[x+1][y]==1)c++;
if(y+1<n && grid[x][y+1]==1)c++;
return c;
}
int islandPerimeter(vector<vector<int>>& grid) {
int count1 = 0;
int count2 = 0;
for(int i = 0;i<grid.size();i++)
{
for(int j = 0;j<grid[0].size();j++)
{
if(grid[i][j]==1)
{
count1++;
count2 += func(grid,grid.size(),grid[0].size(),i,j);
}
}
}
return count1*4-count2*2;
}
};
464. 我能赢吗(位运算,哈希表在dfs中的使用)
dfs
class Solution {
public:
bool res = true;
void dfs(bool b,int maxChoosableInteger, int sum, int desiredTotal,vector<int>& visited)
{
if(sum>=desiredTotal)
{
if(b)res = false;
return;
}
for(int i = 1;i<=maxChoosableInteger;i++)
{
if(visited[i-1]==0)
{
visited[i-1]=1;
sum += i;
b = !b;
dfs(b,maxChoosableInteger,sum,desiredTotal,visited);
b = !b;
sum -= i;
visited[i-1]=0;
}
}
}
bool canIWin(int maxChoosableInteger, int desiredTotal) {
if(desiredTotal==0)return true;
vector<int> visited(maxChoosableInteger,0);
bool b = false;
for(int i = 1;i<=maxChoosableInteger;i++)
{
res = true;
visited = vector<int>(maxChoosableInteger,0);
visited[i-1] = 1;
b= false;
dfs(b,maxChoosableInteger,i,desiredTotal,visited);
if(res)return true;
}
return false;
}
};
class Solution {
public:
bool res = true;
void dfs(bool b,int maxChoosableInteger, int sum, int desiredTotal,int visited)
{
if(sum>=desiredTotal)
{
if(b)res = false;
return;
}
for (int i = 1; i <= maxChoosableInteger; i++)
{
if ((visited & (1 << i)) == 0)
{
dfs(!b, maxChoosableInteger, sum + i, desiredTotal, (visited | (1 << i)));
}
}
}
bool canIWin(int maxChoosableInteger, int desiredTotal) {
if(desiredTotal==0)return true;
bool b = false;
for(int i = 1;i<=maxChoosableInteger;i++)
{
res = true;
b= false;
dfs(b,maxChoosableInteger,i,desiredTotal,1<<i);
if(res)return true;
}
return false;
}
};
class Solution {
public:
bool res = true;
unordered_map<string,int> mp;
void dfs(bool b,int maxChoosableInteger, int sum, int desiredTotal,int visited)
{
if(sum>=desiredTotal)
{
if(b)res = false;
return;
}
string key = to_string(visited) + to_string(sum);
if(mp[key]>0)return;
mp[key]++;
for (int i = 1; i <= maxChoosableInteger; i++)
{
if ((visited & (1 << i)) == 0)
{
dfs(!b, maxChoosableInteger, sum + i, desiredTotal, (visited | (1 << i)));
}
}
}
bool canIWin(int maxChoosableInteger, int desiredTotal) {
if(desiredTotal==0)return true;
bool b = false;
for(int i = 1;i<=maxChoosableInteger;i++)
{
res = true;
b= false;
dfs(b,maxChoosableInteger,i,desiredTotal,1<<i);
if(res)return true;
}
return false;
}
};
int maxChoosableInteger, desiredTotal;
std::map<std::pair<int, int>, int> mp;
// 从(state, sum)这个状态出发能否获胜
bool dfs(int state, int sum) {
// 递归的边界
if (sum >= desiredTotal) return true;
// 记忆化
if (mp.find({state, sum}) != mp.end()) return mp[{state, sum}];
int ret = true;
for (int i = 1; i <= maxChoosableInteger; ++i) {
if ((state & (1 << i)) == 0) {
if (dfs(state | (1 << i), sum + i)) {
ret = false;
break;
}
}
}
return mp[{state, sum}] = ret;
}
bool canIWin(int a, int b) {
maxChoosableInteger = a, desiredTotal = b;
// 如果所有数都被选了(即所有数相加)都还小于desiredTotal, 显然是false
if ((a + 1) * a / 2 < b) return false;
for (int i = 1; i <= a; ++i) {
if (dfs(1 << i, i)) return true;
}
return false;
}
};
465. 最优账单平衡
class Solution {
public:
int res = INT_MAX;
void dfs(vector<int>&vt,int p,int path)
{
bool b = true;
for(auto&v:vt)
{
if(v!=0){b=false;break;}
}
if(b)
{
res = min(res,path);
return;
}
for(int i = p;i<vt.size();i++)
{
for(int j = i+1;j<vt.size();j++)
{
if((vt[i]>0 && vt[j]<0)||(vt[j]>0 && vt[i]<0))
{
int temp = vt[i];
vt[i]=0;
vt[j] += temp;
dfs(vt,p+1,path+1);
vt[i]=temp;
vt[j] -= temp;
}
}
}
}
int minTransfers(vector<vector<int>>& transactions) {
unordered_map<int,int> mp;
for(auto&t:transactions)
{
mp[t[0]]-=t[2];
mp[t[1]]+=t[2];
}
vector<int> vt;
for(auto&m:mp)
{
if(m.second!=0)vt.push_back(m.second);
}
dfs(vt,0,0);
return res;
}
};
467. 环绕字符串中唯一的子字符串
class Solution {
public:
bool isContinous(char prev, char curr) {
if (prev == 'z') return curr == 'a';
return prev + 1 == curr;
}
int findSubstringInWraproundString(string p) {
vector<int> dp(26, 0);
int N = p.size();
int k = 0;
for (int i = 0; i < N; ++i) {
if (i > 0 && isContinous(p[i - 1], p[i])) {
++k;
} else {
k = 1;
}
dp[p[i] - 'a'] = max(dp[p[i] - 'a'], k);
}
return accumulate(dp.begin(), dp.end(), 0);
}
};
作者:da-li-wang
链接:https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string/solution/c-yi-ci-bian-li-by-da-li-wang-6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
468. 验证IP地址
class Solution {
public:
string validIPAddress(string IP) {
int len = IP.size();
int i = 0;
vector<int> ipv4;
int count = 0;
while(i<len)
{
int j = i;
while(i<len && IP[i]!='.')i++;
if(j==i)break;
auto t = IP.substr(j,i-j);
bool b = false;
for(auto&t1:t)
{
if(!('0'<=t1 && t1<='9'))b=true;
}
if(b)break;
if((t.size()>=4)||(t.size()>1 && t[0]=='0'))break;
if(stoi(t)<0 || stoi(t)>255)break;
ipv4.push_back(stoi(t));
i++;
}
if(ipv4.size()==4 && i==IP.size()+1)return "IPv4";
i = 0;
vector<string> ipv6;
while(i<len)
{
int j = i;
while(i<len && IP[i]!=':')i++;
if(j==i)break;
auto t = IP.substr(j,i-j);
if(t.size()>4)break;
bool b = false;
for(auto&t1:t)
{
if(!('0'<=t1 && t1<='9') && !('A'<=t1 && t1<='F') && !('a'<=t1 && t1<='f'))b=true;
}
if(b)break;
ipv6.push_back(t);
i++;
}
if(ipv6.size() == 8 && i==len+1)return "IPv6";
return "Neither";
}
};
470. 用 Rand7() 实现 Rand10()
注意(a-1)
7+b而不是a
b
// The rand7() API is already defined for you.
// int rand7();
// @return a random integer in the range 1 to 7
class Solution {
public:
int rand10() {
while(1)
{
int a = rand7();
int b = rand7();
int c = (a-1)*7+b;
if(c<=40)
{
return (double)c/4==c/4?c/4:c/4+1;
}
}
}
};
472. 连接词
class Solution {
public:
bool b = false;
vector<string> path;
void dfs(unordered_set<string> st,string w,int p)
{
if(p==w.size())
{
if(path.size()>=2) b=true;
return;
}
for(int i = p+1;i<=w.size();i++)
{
auto t = w.substr(p,i-p);
if(st.find(t)!=st.end())
{
path.push_back(t);
dfs(st,w,i);
path.pop_back();
}
}
}
vector<string> findAllConcatenatedWordsInADict(vector<string>& words) {
unordered_set<string> st;
for(auto&w:words)
{
st.insert(w);
}
vector<string> res;
for(auto&w:words)
{
path.clear();
b = false;
dfs(st,w,0);
if(b)res.push_back(w);
}
return res;
}
};
473. 火柴拼正方形
class Solution {
public:
bool res = false;
vector<int> vt;
void dfs(int p,vector<int> nums, int len)
{
if (res)return;
bool t = false;
if(p==nums.size())
{
if (vt[0] == len && vt[1] == len && vt[2] == len && vt[3] == len)res = true;
return;
}
for (int i = 0; i < 4; i++)
{
if (vt[i] + nums[p] <= len)
{
vt[i] += nums[p];
dfs(p+1,nums,len);
vt[i] -= nums[p];
}
}
}
static bool cmp(int a,int b)
{
return a>b;
}
bool makesquare(vector<int> nums) {
if (nums.empty())return false;
int sum = 0;
for (auto&n : nums)sum += n;
if (sum % 4 != 0)return false;
int len = sum / 4;
for (auto&n : nums)
{
if (n > len)return false;
}
sort(nums.begin(),nums.end(),cmp);
vt = vector<int>(4, 0);
dfs(0,nums,len);
return res;
}
};
474. 一和零(背包)
int findMaxForm(vector<string>& strs, int m, int n ) {
vector<vector<int>> nums (strs.size() , vector<int>(2 , 0));
for(int i = 0 ; i < strs.size() ; i++)
{
for(auto ch : strs[i])
{
if(ch == '0') (nums[i][0])++;
else (nums[i][1])++;
}
}
vector<vector<vector<int>>> dp(strs.size() + 1, vector<vector<int>>
(m + 1 , vector<int>(n + 1 , 0)));
for(int i = 1 ; i < strs.size() + 1; i ++ )
for(int cap_0 = 0 ; cap_0 < m + 1 ; cap_0++ )
for(int cap_1 = 0 ; cap_1 < n + 1 ; cap_1++)
{
if(cap_0 - nums[i - 1][0] >= 0 && cap_1 - nums[i - 1][1] >= 0)
dp[i][cap_0][cap_1] =
max(dp[i - 1][cap_0][cap_1] , dp[i - 1][cap_0 - nums[i -1][0]][cap_1 - nums[i - 1][1]] + 1 );
else dp[i][cap_0][cap_1] = dp[i - 1][cap_0][cap_1];
}
return dp[strs.size()][m][n];
}
作者:rocky-12
链接:https://leetcode-cn.com/problems/ones-and-zeroes/solution/duo-wei-bei-bao-wen-ti-wei-jian-hua-ban-ben-by-roc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
01背包问题,但是是二维背包,但是思路是一样的
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
//01背包,两个背包,需要用二维的情况
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(auto str:strs)
{
int zeros = 0 , ones = 0;
for(auto c:str)
{
if(c=='0')zeros++;
else ones++;
}
for(int i = m; i>= zeros ;i--)
{
for(int j = n ; j>= ones ;j--)
{
dp[i][j] = max (dp[i][j], dp[i-zeros][j-ones]+1);
}
}
}
return dp[m][n];
}
};
475. 供暖器
class Solution {
public:
int findRadius(vector<int>& houses, vector<int>& heaters) {
sort(houses.begin(),houses.end());
sort(heaters.begin(),heaters.end());
int res = 0;
for(auto&h:houses)
{
int m =0;
auto iter = lower_bound(heaters.begin(),heaters.end(),h);
if(iter == heaters.end())m = h-heaters.back();
else if( iter== heaters.begin())m = heaters.front()-h;
else
{
int i = iter-heaters.begin();
m = min(heaters[i]-h,h-heaters[i-1]);
}
res = max(res,m);
}
return res;
}
};
476. 数字的补数
class Solution {
public:
int findComplement(int num) {
int tmp = 1;
while (tmp < num)
{
tmp <<= 1;
tmp += 1;
}
return (tmp^num);
}
};
作者:im-me
链接:https://leetcode-cn.com/problems/number-complement/solution/yi-huo-by-im-me/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
477. 汉明距离总和
class Solution {
public:
int totalHammingDistance(vector<int>& nums) {
vector<int> dp(32,0);
int res = 0;
for(int i = 0;i<32;i++)
{
int c = 1<<i;
int one =0,zero = 0;
for(auto&n:nums)
{
if((n&(c))==0)zero++;
else one++;
}
res += zero*one;
}
return res;
}
};
478. 在圆内随机生成点
class Solution {
public:
double r,x,y;
Solution(double radius, double x_center, double y_center) {
r = radius;
x = x_center;
y = y_center;
}
vector<double> randPoint() {
double a = 2* (double)rand() /RAND_MAX-1;
double b = 2* (double)rand() /RAND_MAX-1;
if(a*a+b*b>1)return randPoint();
return {x+r*a,y+r*b};
}
};
/**
* Your Solution object will be instantiated and called as such:
* Solution* obj = new Solution(radius, x_center, y_center);
* vector<double> param_1 = obj->randPoint();
*/
480. 滑动窗口中位数
class Solution {
public:
double func(vector<int>& nums)
{
int len = nums.size();
if(len%2==0)return ((double)nums[len/2-1]+(double)nums[len/2])/2;
return nums[len/2];
}
void func(vector<int>&win, int a,int b)
{
auto iter = lower_bound(win.begin(),win.end(),a);
win.insert(iter,a);
auto iter2 = lower_bound(win.begin(),win.end(),b);
win.erase(iter2);
}
vector<double> medianSlidingWindow(vector<int>& nums, int k) {
vector<int> win(nums.begin(),nums.begin()+k);
vector<double> res;
sort(win.begin(),win.end());
res.push_back(func(win));
for(int i = k;i<nums.size();i++)
{
func(win,nums[i],nums[i-k]);
res.push_back(func(win));
}
return res;
}
};
481. 神奇字符串
class Solution {
public:
int magicalString(int n) {
string s= "122";
string s1 = "1";
int j = 1;
bool b= true;
while(j<n)
{
if(s1.back()=='1')
{
if(s[j]=='1')s1 += "2";
else s1 += "22";
}
else
{
if(s[j]=='1') s1 +="1";
else s1 += "11";
}
s = s1;
j++;
}
int res = 0;
for(int i = 0;i<n;i++)
{
if(s[i]=='1')res++;
}
return res;
}
};
482. 密钥格式化
class Solution {
public:
string licenseKeyFormatting(string S, int K) {
string s = "";
for(auto&c:S)
{
if(c!='-')s+=c;
}
string res;
int i = s.size()-1;
while(i>=0)
{
if(i>K-1)
{
auto temp = s.substr(i-K+1,K);
for(auto&t:temp)
{
if(t>='a' && t<='z')t = t-'a' + 'A';
}
res = temp + "-" + res;
i -= K;
}
else
{
auto temp = s.substr(0,i+1);
for(auto&t:temp)
{
if(t>='a' && t<='z')t = t-'a' + 'A';
}
res = temp + "-" + res;
break;
}
}
res.pop_back();
return res;
}
};
487. 最大连续1的个数 II
class Solution {
public:
int findMaxConsecutiveOnes(vector<int>& nums) {
int res = 0;
int i = 0;
int count1 = 0;
int count0 = 0;
int j = 0;
while(i<nums.size())
{
if(nums[i]==1)
{
count1++;
res = max(res,count0+count1);
i++;
}
else
{
if(count0==0)
{
count0++;
res = max(res,count0+count1);
i++;
}
else
{
while(j<i && nums[j]==1)
{
j++;
count1--;
}
j++;
count0--;
i++;
}
}
}
return res;
}
};
488. 祖玛游戏
这种dfs没有考虑特殊的情况
class Solution {
public:
vector<int> visited;
int path = 0;
int res = INT_MAX;
void func1(string& board1)
{
if (board1.size() <= 2)return;
bool b = false;
int i = 0;
while (i < board1.size() )
{
int j = i;
while (i < board1.size() && board1[i] == board1[j])i++;
if (i - j >= 3)
{
board1.erase(board1.begin()+j,board1.begin()+i);
b = true;
}
}
if (b) func1(board1);
return;
}
void func(string & board, char a)
{
if (board.size() == 1) { board += a; return; }
for (int i = 0; i < board.size() - 1; i++)
{
if (board[i] == a && board[i + 1] == a)
{
board.insert(board.begin() + i, a);
func1(board);
return;
}
}
board += a;
return;
}
void dfs(string& board,string& hand)
{
if (board.empty())
{
res = min(res, path);
return;
}
for (int i = 0; i < hand.size(); i++)
{
if (visited[i] == 0)
{
path++;
visited[i] = 1;
auto temp = board;
func(board, hand[i]);
dfs(board,hand);
board = temp;
path--;
visited[i] = 0;
}
}
}
int findMinStep(string board, string hand) {
visited = vector<int>(hand.size(), 0);
dfs(board,hand);
if (res == INT_MAX)return -1;
return res;
}
};
489. 扫地机器人
class Solution {
public:
void dfsRobot(Robot& robot, unordered_set<string>& visit, int x, int y, int dir) {
int d[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
robot.clean();
for (int i = 0; i < 4; ++i) {
int newDir = (dir + i) % 4;
int x1 = x + d[newDir][0];
int y1 = y + d[newDir][1];
string key = to_string(x1) + "," + to_string(y1);
if(!visit.count(key)&&robot.move()){
visit.insert(key);
dfsRobot(robot, visit, x1, y1, newDir);
robot.turnLeft();
robot.turnLeft();
robot.move();
robot.turnLeft();
robot.turnLeft();
}
robot.turnLeft();
}
}
void cleanRoom(Robot& robot) {
unordered_set<string> visited;
visited.insert(to_string(0)+","+to_string(0));
dfsRobot(robot, visited, 0, 0, 0);
}
};
作者:mike-meng
链接:https://leetcode-cn.com/problems/robot-room-cleaner/solution/you-yi-si-de-ti-mu-by-mike-meng/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
490. 迷宫
学习用两个数组减少代码量的方式
class Solution {
public:
bool hasPath(vector<vector<int>>& maze, vector<int>& start, vector<int>& destination) {
queue<vector<int>> qt;
qt.push(start);
unordered_set<string> st;
int m = maze.size(),n = maze[0].size();
st.insert(to_string(start[0])+","+to_string(start[1]));
vector<int> a = {1,0,-1,0};
vector<int> b = {0,1,0,-1};
while(!qt.empty())
{
int len = qt.size();
for(int i = 0;i<len;i++)
{
auto temp = qt.front();qt.pop();
st.insert(to_string(temp[0])+","+to_string(temp[1]) );
int x = temp[0],y=temp[1];
for(int p = 0;p<4;p++)
{
int x1 = x + a[p];
int y1 = y + b[p];
while(x1<m && x1>=0 && y1<n && y1>=0 && maze[x1][y1]==0)
{
if(x1==destination[0] && y1==destination[1] )
{
return true;
}
x1 = x1 +a[p];
y1 = y1 + b[p];
}
x1 = x1-a[p];
y1 = y1-b[p];
if(x1<m && x1>=0 && y1<n && y1>=0 && maze[x1][y1]==0 && st.find(to_string(x1)+","+to_string(y1))==st.end())
{
qt.push({x1,y1});
}
}
}
}
return false;
}
};
491. 递增子序列
class Solution {
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
int len = nums.size();
vector<vector<vector<int>>> dp(len);
set<vector<int>> res;
for(int i = 1;i<len;i++)
{
for(int j = 0;j<i;j++)
{
if(nums[j]<=nums[i])
{
res.insert({nums[j],nums[i]});
dp[i].push_back({nums[j],nums[i]});
for(auto &a:dp[j])
{
auto a1 = a;
a1.push_back(nums[i]);
res.insert(a1);
dp[i].push_back(a1);
}
}
}
}
vector<vector<int>> r(res.begin(),res.end());
return r;
}
};
dfs的方法比动态规划要快一点,而且这道题使用string记录的也不方便,因为path的个数不固定,每次还需要全部遍历转成string,态麻烦了
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
//unordered_set<string> st;
void dfs(int start,vector<int> nums)
{
if(path.size()>=2)res.push_back(path);
for(int i = start;i<nums.size();i++)
{
if(path.empty())
{
//st.insert(nums[i]);
path.push_back(nums[i]);
dfs(i+1,nums);
path.pop_back();
//st.erase(nums[i]);
}
else
{
if(nums[i]>=path.back())
{
//st.insert(nums[i]);
path.push_back(nums[i]);
dfs(i+1,nums);
path.pop_back();
//st.erase(nums[i]);
}
}
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
dfs(0,nums);
set<vector<int>> r(res.begin(),res.end());
vector<vector<int>> rr(r.begin(),r.end());
return rr;
}
};
这里的st放在了dfs的里面不是很好理解,但是比较高效
class Solution {
public:
vector<vector<int>> ans;
void dfs(vector<int>& nums, vector<int>& path, int start) {
if (path.size() >= 2) ans.push_back(path);
if (start >= nums.size()) return;
unordered_set<int> s;
// 如果set里已经记录了当前的值,则跳过;因为之前唤起的dfs里会把之后所有的同样的值都选中;
// 只需要考虑从之后开始选中的重复的值即可
for (int i = start; i < nums.size(); i++) {
if (s.find(nums[i]) != s.end()) continue;
if (path.size() == 0) {
s.insert(nums[i]);
path.push_back(nums[i]);
dfs(nums, path, i+1);
path.pop_back();
} else {
if (nums[i] >= path.back()) {
s.insert(nums[i]);
path.push_back(nums[i]);
dfs(nums, path, i+1);
path.pop_back();
}
}
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
vector<int> path;
dfs(nums, path, 0);
return ans;
}
};
作者:wfnuser
链接:https://leetcode-cn.com/problems/increasing-subsequences/solution/c-shen-du-you-xian-sou-suo-jian-zhi-pan-zhong-by-w/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
493. 翻转对(树状数组)
struct FinTree {
vector<int> tree;
int size;
FinTree(int _size) : size(_size) {
tree = vector<int> (size, 0);
};
int lowbit(int n) {
return n & (-n);
}
// 向上更新
void updateTree(int i, int count) {
while (i<size) {
tree[i] += count;
i += lowbit(i);
}
}
// 向下统计
int queryTree(int i) {
int res = 0;
while (i>0) {
res += tree[i];
i -= lowbit(i);
}
return res;
}
};
class Solution {
public:
int reversePairs(vector<int>& nums) {
int size = nums.size();
if (size == 0) return 0;
FinTree ft(size + 1);
// 离散化 排序去重 用Set也行
vector<int> v (nums);
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
int count = 0;
// 从后向前遍历
for (int i=size-1; i>=0; --i) {
// 查找num/2
count += ft.queryTree(lower_bound(v.begin(), v.end(), ceil(nums[i] / 2.)) - v.begin());
// 更新num
ft.updateTree(lower_bound(v.begin(), v.end(), nums[i]) - v.begin() + 1, 1);
}
return count;
}
};
作者:7787
链接:https://leetcode-cn.com/problems/reverse-pairs/solution/c-shu-zhuang-shu-zu-by-7787/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
494. 目标和
还是dfs主体没搞清楚,
class Solution {
private:
int num;
int len;
public:
void dfs(int pos, int sum, vector<int>& nums, int S)
{
if(pos == len)
{
if(sum==S){num++;}
return;
}
for(int i = pos ; i< len ;i++)
{
sum = sum+nums[i];
dfs(pos+1,sum,nums,S);
sum=sum-nums[i]*2;
dfs(pos+1,sum,nums,S);
}
}
int findTargetSumWays(vector<int>& nums, int S) {
len = nums.size();
num = 0;
dfs(0,0,nums,S);
return num;
}
};
在dfs的地方不用遍历,直接传递那个,那个值每次加1就可以起到遍历的作用了,但是上一道题又需要进行遍历,现在什么时候需要遍历什么时候不需要还没有弄得很清楚
class Solution {
public:
int res = 0;
void dfs(int p ,int sum,vector<int>&nums,int S)
{
if(p==nums.size())
{
if(sum==S)res++;
return;
}
dfs(p+1,sum+nums[p],nums,S);
dfs(p+1,sum-nums[p],nums,S);
}
int findTargetSumWays(vector<int>& nums, int S) {
dfs(0,0,nums,S);
return res;
}
};
动态规划
背包问题01背包不可重复,背包在外,进行逆序
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int sum = 0;
for(auto num:nums){sum +=num;}
if(sum<S || (sum+S)%2==1)return 0;
int w = (S+sum)/2;
vector<int> dp(w+1,0);
dp[0]=1;
for(auto num:nums)
{
for(int i = w ; i>=num ;i--)
{
dp[i] = dp[i] + dp[i-num];
}
}
return dp[w];
}
};
495. 提莫攻击
class Solution {
public int findPoisonedDuration(int[] timeSeries, int duration) {
int n = timeSeries.length;
if (n == 0) return 0;
int total = 0;
for(int i = 0; i < n - 1; ++i)
total += Math.min(timeSeries[i + 1] - timeSeries[i], duration);
return total + duration;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/teemo-attacking/solution/ti-mo-gong-ji-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
496. 下一个更大元素 I
开一个map将小数组中的数字存进去,方便后续查找。空间换时间的思路
然后遍历大数组,同时维持一个栈
如果当前这个数比栈顶大,就将当前栈pop出来,同时就代表当前pop的这个数在右侧最大的就是当前这个数
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
map<int,int> mp;
stack<int> stack;
for(int value: nums1) {
mp[value] = -1;
}
for(int i=0;i<nums2.size();i++) {
while (!stack.empty()&&stack.top()<nums2[i]) {
mp[stack.top()] = nums2[i];
stack.pop();
}
stack.push(nums2[i]);
}
for(int i=0;i<nums1.size();i++) {
nums1[i] = mp[nums1[i]];
}
return nums1;
}
};
作者:isnine
链接:https://leetcode-cn.com/problems/next-greater-element-i/solution/c-by-isnine/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> vt;
vector<int> res(nums1.size(),-1);
unordered_map<int,int> mp;
for(int i = 0; i<nums2.size() ;i++)
{
while(!vt.empty() && nums2[i]>vt.back())
{
mp[vt.back()]=nums2[i];
vt.pop_back();
}
vt.push_back(nums2[i]);
}
for(int i = 0;i<nums1.size();i++)
{
if(mp.find(nums1[i])!=mp.end())res[i]=mp[nums1[i]];
}
return res;
}
};
498. 对角线遍历
class Solution {
public:
static bool isok(int i, int j, int m, int n, string sta)
{
if (sta == "rightup")
{
return i - 1 >= 0 && j + 1 < n;
}
else return j - 1 >= 0 && i + 1 < m;
}
vector<int> findDiagonalOrder(vector<vector<int>> matrix) {
if(matrix.empty())return {};
string sta = "rightup";
int m = matrix.size();
int n = matrix[0].size();
int i = 0, j = 0;
vector<int> res;
while (1)
{
if (i == m - 1 && j == n - 1)
{
res.push_back(matrix[i][j]); break;
}
while (sta == "rightup" && isok(i, j, m, n, sta))
{
res.push_back(matrix[i][j]);
i--; j++;
}
res.push_back(matrix[i][j]);
if (j == n - 1)i++;
else j++;
sta = "leftdown";
if (i == m - 1 && j == n - 1)
{
res.push_back(matrix[i][j]); break;
}
while (sta == "leftdown" && isok(i, j, m, n, sta))
{
res.push_back(matrix[i][j]);
i++; j--;
}
res.push_back(matrix[i][j]);
if (i == m - 1)j++;
else i++;
sta = "rightup";
}
return res;
}
};
499. 迷宫 III
复杂的dfs
class Solution {
public:
bool static isok(int i, int j, int m, int n,vector<vector<int>>& maze)
{
return i >= 0 && j >= 0 && i < m && j < n && maze[i][j]!=1;
}
static bool cmp(pair<int,string> a, pair<int,string> b)
{
if(a.first==b.first)return a.second<b.second;
return a.first<b.first;
}
string findShortestWay(vector<vector<int>> maze, vector<int> ball, vector<int> hole) {
queue<pair<string, vector<int>>> qt;
vector<char> s = { 'u','d','l','r' };
vector<int> a = { -1,1,0,0 };
vector<int> b = { 0,0,-1,1 };
int m = maze.size();
int n = maze[0].size();
qt.push({ "u",{ball[0],ball[1]} });
qt.push({ "d",{ball[0],ball[1]} });
qt.push({ "l",{ball[0],ball[1]} });
qt.push({ "r",{ball[0],ball[1]} });
unordered_set<string> st;
vector<string> res;
while (!qt.empty())
{
int len = qt.size();
for (int i = 0; i < len; i++)
{
auto temp = qt.front(); qt.pop();
string sign = temp.first;
int x = temp.second[0];
int y = temp.second[1];
st.insert(to_string(x) + to_string(y));
for (int i = 0; i < 4; i++)
{
while (sign.back() == s[i] && isok(x + a[i], y + b[i], m, n,maze))
{
if (x+a[i] == hole[0] && y+b[i] == hole[1])
{
res.push_back(sign);
}
x += a[i]; y += b[i];
}
if (st.find(to_string(x) + to_string(y)) == st.end())
{
for (auto&s1 : s)qt.push({ sign + s1,{x,y} });
}
}
}
}
if (res.empty())return "impossible";
sort(res.begin(), res.end());
res.erase(unique(res.begin(),res.end()),res.end());
vector<pair<int,string>> r;
for(auto &r1:res)
{
int t = 0;
int x = ball[0],y=ball[1];
for(auto & r11:r1)
{
for(int i = 0;i<4;i++)
{
while (r11 == s[i] && isok(x + a[i], y + b[i], m, n,maze))
{
if (x+a[i] == hole[0] && y+b[i] == hole[1])
{
t++;break;
}
t++;
x += a[i]; y += b[i];
}
}
}
r.push_back({t,r1});
}
sort(r.begin(),r.end(),cmp);
return r.front().second;
}
};