第三次周赛 总结:是的,我在进步中。。。
Posted 诚威_lol_中大努力中
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第三次周赛 总结:是的,我在进步中。。。相关的知识,希望对你有一定的参考价值。
T1:最长平衡子字符串:
给你一个仅由 0
和 1
组成的二进制字符串 s
。
如果子字符串中 所有的 0
都在 1
之前 且其中 0
的数量等于 1
的数量,则认为 s
的这个子字符串是平衡子字符串。请注意,空子字符串也视作平衡子字符串。
返回 s
中最长的平衡子字符串长度。
子字符串是字符串中的一个连续字符序列。
解:
1.关键:
(1)主要还是 贪心的 过程
(2)遍历一次,每次记录当前的 '0' 或者 '1'
(3)具体情况,还是要分情况讨论,具体见代码,别忘了当s[n-1] == '1' 时的边界情况即可
2.代码:
class Solution
public:
int findTheLongestBalancedSubstring(string s)
//所有'0' 都在 '1'之前, 而且 0的数量必须等于1的数量,return cnt*2
//直接 贪心遍历即可
int cnt_0 = 0,cnt_1 = 0 , ans = 0;
int n = s.size();
//--
for(int i=0;i<n;i++)
//记录当前位置的 '0' 或者 '1'
if(s[i] == '0')
cnt_0++;
else if(s[i]=='1')
cnt_1++;
//--然后 :处理刷新操作 和 得到ans的操作:
//case1:if(i>0 && s[i-1] == '1' && s[i] == '0') 此时:更新ans并且刷新 cnt_0 和 cnt_1
if(i>0 && s[i-1] == '1' && s[i] == '0')
cnt_0--;
int num = min(cnt_0,cnt_1);
ans = max(ans,num);
cnt_0 = 1;
cnt_1 = 0; //刷新
//最后一个位置还是需要考虑一下的:
if(s[n-1] == '1')
int num = min(cnt_0,cnt_1);
ans = max(ans,num);
return ans*2;
;
T2:转换为二维数组
给你一个整数数组 nums
。请你创建一个满足以下条件的二维数组:
- 二维数组应该 只 包含数组
nums
中的元素。 - 二维数组中的每一行都包含 不同 的整数。
- 二维数组的行数应尽可能 少 。
返回结果数组。如果存在多种答案,则返回其中任何一种。
请注意,二维数组的每一行上可以存在不同数量的元素。
解:
1.关键:
之前没有读懂题目,其实就是 一行中每个元素都不同
直接利用一个map容器,记录每个元素nums[i] 重复的次数
好吧,本质上就是贪心算法 中的 “木桶 短板理论”,
行数 : 由重复最多的哪个元素的 重复次数决定
(1)先预处理,将答案存到二维数组ans中,用map1记录<val,cnt>,用max记录当前最大的重复次数
(2)从头 对nums数组进行遍历,并且分2中情况进行讨论
<1>这个元素nums[i]重复次数比max还要多,需要建立 新的一行
<2>否则,这个元素可以到ans[map1[nums[i]]].push_back(nums[i])中即可
2.代码:
class Solution
public:
vector<vector<int>> findMatrix(vector<int>& nums)
//我.。。,之前没有读懂题目,其实就是 一行中每个元素都不同
//直接利用一个map容器,记录每个元素nums[i] 重复的次数
//好吧,本质上就是贪心算法 中的 “木桶 短板理论”,
//行数 : 由重复最多的哪个元素的 重复次数决定
//1.预处理:
vector<vector<int>> ans;
unordered_map<int,int> map1;//<val,cnt> ,打擂台,找到cnt中的那个最大值
int max = 0;
int n= nums.size();
//2.从头 对nums数组遍历一次
for(int i=0;i<n;i++)
map1[nums[i]]++;
//(1)这个元素重复次数比max还要多,需要建立 新的一行
if(map1[nums[i]] > max)
max = map1[nums[i]];
vector<int> new_col;
new_col.push_back(nums[i]); //把这个元素加入进去
//把这个行加入到ans中
ans.push_back(new_col);
//(2)否则,这个元素可以到ans[map1[nums[i]]].push_back(nums[i])中即可
else
ans[map1[nums[i]]-1].push_back(nums[i]); //(次数-1)等于对应行的下标
return ans;
;
T3:老鼠 和 奶酪
有两只老鼠和 n
块不同类型的奶酪,每块奶酪都只能被其中一只老鼠吃掉。
下标为 i
处的奶酪被吃掉的得分为:
- 如果第一只老鼠吃掉,则得分为
reward1[i]
。 - 如果第二只老鼠吃掉,则得分为
reward2[i]
。
给你一个正整数数组 reward1
,一个正整数数组 reward2
,和一个非负整数 k
。
请你返回第一只老鼠恰好吃掉 k
块奶酪的情况下,最大 得分为多少。
解:
1.关键:
又是一个贪心的问题: 只要计算reward1[i] 和 reward2[i] 的差值数组diff[i]即可
(1)因为需要取k个reward1,所以diff[i] = reward1[i] - reward2[i]
(2)然后,找到diff[i]中最大的那k个, 求和sum_diff
直接对diff进行排序即可,然后从后面取到k个元素的和
(3)计算 reward2中的所有和 sum2, 最终 ans = sum2 + sum_diff
总的来说,就一点,尽可能的让第一只老鼠吃到的那k个奶酪“赚得相对于让第二只老鼠来吃 更多一些”
2.代码:
class Solution
public:
int miceAndCheese(vector<int>& reward1, vector<int>& reward2, int k)
//简单,又是一个贪心的问题: 只要计算reward1[i] 和 reward2[i] 的差值数组diff[i]即可
//因为需要取k个reward1,所以diff[i] = reward1[i] - reward2[i]
//然后,找到diff[i]中最大的那k个, 求和sum_diff
//直接对diff进行排序即可,然后从后面取到k个元素的和
//计算 reward2中的所有和 sum2, 最终 ans = sum2 + sum_diff
int n = reward1.size();
int sum_diff = 0;
int sum2 = 0;
vector<int> diff(n,0);
for(int i=0;i<n;i++)
sum2+= reward2[i];
diff[i] = reward1[i] - reward2[i];
//排序
sort(diff.begin(),diff.end()); //从后往前求和
for(int i=n-1;i>=(n-k);i--)
sum_diff += diff[i];
return sum2+sum_diff;
;
T4:最少翻转操作数
给你一个整数 n
和一个在范围 [0, n - 1]
以内的整数 p
,它们表示一个长度为 n
且下标从 0 开始的数组 arr
,数组中除了下标为 p
处是 1
以外,其他所有数都是 0
。
同时给你一个整数数组 banned
,它包含数组中的一些位置。banned
中第 i 个位置表示 arr[banned[i]] = 0
,题目保证 banned[i] != p
。
你可以对 arr
进行 若干次 操作。一次操作中,你选择大小为 k
的一个 子数组 ,并将它 翻转 。在任何一次翻转操作后,你都需要确保 arr
中唯一的 1
不会到达任何 banned
中的位置。换句话说,arr[banned[i]]
始终 保持 0
。
请你返回一个数组 ans
,对于 [0, n - 1]
之间的任意下标 i
,ans[i]
是将 1
放到位置 i
处的 最少 翻转操作次数,如果无法放到位置 i
处,此数为 -1
。
- 子数组 指的是一个数组里一段连续 非空 的元素序列。
- 对于所有的
i
,ans[i]
相互之间独立计算。 - 将一个数组中的元素 翻转 指的是将数组中的值变成 相反顺序 。
解:
1.关键:
备注这里借鉴了 妙蛙种子 的思路,添加了一些个人的理解
(1)先考虑特殊情况,k==1时,不能跳到其它位置
(2)将banned数组转移到 一个set中,方便访问
(3)把除了p下标位置 和 ban中的下标位置,分奇偶放到2个set容器中:
之所以这么做,就是因为 每次跳跃的区间向右移动一次后,从当前的下标位置now可以达到的下一个位置now' 其实向左 移动了2个位置,所以,对于任何一个k值,先看now+k-1也就是向右最远可以跳到的下标位置时 奇数 还是 偶数,之后就只能在 奇数或者 偶数容器set中去找下一个可以到达的位置
注意:只要在 最左边可以到达的位置 和 最右边可以到达的位置之间的 所有的奇数 或者 偶数 set中的位置,从当前的now位置下一次跳跃都是 可以到达的!!!
(4)利用一个 队列容器q进行bfs 广搜:
初值:起点位置 --就是p点下标,先入队 ,-- 一下解释 bfs的while循环的具体代码的含义
<1>取出队首元素 , 并且记得出队
<2>先Left可以移动 和 向Right可以移动的 最大距离:
<3>//悟了:之所以计算x = (now+k-1)%2作为st的下标
//是因为,从now这个点可以到达的点之间 都是相隔2位的,这一点见csdn笔记
//从st[x]中找到刚好大于now+L的位置
//然后,从左 到右,然所有now可以到达的位置全部到达一次
2.具体代码如下:
class Solution
public:
vector<int> minReverseOperations(int n, int p, vector<int>& banned, int k)
//审题:
//第一:只有下标 p 位置为1
//第二:banned[i]这个下标位置 永远不能为1
//第三:每一次操作,选择一个大小为k的子数组,并反转它
//保证,每次反转后,这个唯一的“1”还是不会到达banned[i]这个下标
//也就是说arr[banned[i]] == 0 恒成立
//第四:返回一个一维数组vector<int> ans
//ans[i]--的含义是 将唯一的1 移动到下标i位置需要的最少“操作次数”
//不能在某一次移动的结果中让banned[i]位置变成1
//如果做不到,ans[i] = -1即可
//开始动手:
//思路:算了,先借鉴 妙蛙种子的 思路好了
//(1)特殊
vector<int> ans(n,-1);
if(k == 1)
ans[p] = 0;
return ans;
//(2)将banned数组转移到 一个set中,方便访问
unordered_set<int> ban;
for(auto item:banned)
ban.insert(item);
//(3)把除了p下标位置 和 ban中的下标位置,分奇偶放到2个set容器中:
set<int> st[2];
for(int i=0;i<n;i++)
if(i!=p && ban.count(i) == 0)
st[i%2].insert(i);
//(4)利用一个 队列容器q进行bfs 广搜:
queue<int> q;
ans[p] = 0; // 初值:起点位置(相当于 一个跳跃游戏)
q.push(p);
//while循环进行搜索 和 update
while(!q.empty())
//<1>取出队首元素 , 并且记得出队
int now = q.front(); q.pop();
//<2>先Left可以移动 和 向Right可以移动的 最大距离:
int L = max(-(k-1) , k-1 - 2*now);
int R = min(k-1 ,(n-1)-(k-1)+(n-1)-2*now);
//<3>
//悟了:之所以计算x = (now+k-1)%2作为st的下标:
//是因为,从now这个点可以到达的点之间 都是相隔2位的,这一点见csdn笔记
int x = (now+k-1)%2;
//从st[x]中找到刚好大于now+L的位置
auto it =st[x].lower_bound(now+L);
//然后,从左 到右,然所有now可以到达的位置全部到达一次
while(it!= st[x].end())
if(*it > now+R)
break; //已经超出可以到达的 最右边的位置了
//访问这个位置,并且更新ans,同时从st[x]中删除这个位置
ans[*it] = ans[now] + 1;
q.push(*it); //入队。作为之后的起点
it = st[x].erase(it);//删除后,返回下一个位置的 迭代器
return ans;
;
总结part:
这一次明显在思维上有所进步,能够独立思考出 很多东西,而且我发现,如果一边嗑巴西松子一边思考,更容易 集中注意的 思考出大体的思路!非常美妙
ssm框架整合-过程总结(第三次周总结)
本周主要是完成前端界面和后端的整合。
犹豫前后端的工作完成程度不一致,只实现了部分整合。
登录界面。
可能自己最近没有把重心放在短学期的项目上,导致我们工作的总体进度都要比别慢。
虽然我们只是三个人的小组,但我觉得还是需要一位同学担起带领整个团队的重任,不然可能8周结束后都不能完成任务。
犹豫前端方面,组员不能及时的完成任务,所以作为后端的我,需要及时跟上,先放一下后端的任务,帮助前端完成任务。
这周主要精力花在了,寻找合适的模版和修改模板上,前端知识没有系统的学习过,自己搭建比较困难,所以选择修改模版的方式,加快前端开发。
这是我修改部分的后台首页。
还有添加菜品页面,也完成了其他的页面,这里不过多展示。
下周目标:
完成后端的大部分设计、和本周设计出来页面的功能实现。
以上是关于第三次周赛 总结:是的,我在进步中。。。的主要内容,如果未能解决你的问题,请参考以下文章