当前位置:   article > 正文

代码随想录算法训练营第2天 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结

代码随想录算法训练营第2天 | 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II ,总结

977 总共花了1.5h,还是很不熟练,问题出在1自己思路太复杂 2 实现时出bug修bug

双指针,一开始自己想的思路有点过于复杂,还分情况讨论 后来发现根本不用

不过两个双指针 时间复杂度都是O(n)

这个版本代码里出现过的问题有:vector后面要push back的话初始化就要设成0好点,后面要是想vec[i]赋值这样初始话要vector<int> res(size,value);这样比较好,找了半天错误其实问题就是 size初始化0和后面push back没统一

  1. vector<int> sortedSquares(vector<int>& nums) {
  2. vector<int> res(0);
  3. //mixed
  4. int n_idx=nums.size()-1;
  5. int p_idx=nums.size();
  6. for (int i=0;i<nums.size();i++){
  7. if(nums[i]>=0){
  8. n_idx=i-1;
  9. p_idx=i;
  10. break;
  11. }
  12. }
  13. cout<<n_idx<<endl<<p_idx<<endl;
  14. int res_idx=0;
  15. while(n_idx>=0 && p_idx<nums.size()){
  16. int n_square=nums[n_idx]*nums[n_idx];
  17. int p_square=nums[p_idx]*nums[p_idx];
  18. if(n_square<p_square){
  19. //res[res_idx++]=n_square;
  20. res.push_back(n_square);
  21. n_idx--;
  22. }
  23. else{
  24. res.push_back(p_square);
  25. p_idx++;
  26. }
  27. }
  28. //if either idx is invalid
  29. //all positive
  30. if(n_idx<0){
  31. for (int i=p_idx;i<nums.size();i++){
  32. res.push_back(nums[i]*nums[i]);
  33. }
  34. }
  35. //all negative
  36. else if(p_idx>=nums.size()){
  37. for (int i=n_idx;i>=0;i--){
  38. res.push_back(nums[i]*nums[i]);
  39. }
  40. }
  41. return res;
  42. }

看了代码随想录的思路,自己又简洁地写了一遍:

其实这个双指针根本不用分情况讨论,全正全负都照样这么写就行,从两头(绝对值最大)一个个比较

  1. vector<int> sortedSquares(vector<int>& nums) {
  2. vector<int> res(nums.size(),0);
  3. int res_idx=nums.size()-1;
  4. int i=0; int j= nums.size()-1;
  5. while(i<=j){
  6. if(nums[i]*nums[i]>nums[j]*nums[j]){
  7. res[res_idx--]=nums[i]*nums[i];
  8. i++;
  9. }
  10. else{
  11. res[res_idx--]=nums[j]*nums[j];
  12. j--;
  13. }
  14. }
  15. return res;
  16. }

209 是medium 先暴力写了一遍,发现自己写暴力都没那么熟练,会出错:

sum忘记内循环重置0,最大值可以用INT32_MAX,这个O n*2,leetcode过不了

  1. int minSubArrayLen(int target, vector<int>& nums) {
  2. int len=100000;
  3. int sum=0;
  4. int new_len=0;
  5. for(int i=0;i<nums.size();i++){
  6. sum=0;
  7. for(int j=i;j<nums.size();j++){
  8. sum+=nums[j];
  9. if(sum>=target){
  10. len = std::min( j - i + 1, len);
  11. break;
  12. }
  13. }
  14. }
  15. return (len==100000)?0:len;
  16. }

然后自己想了个双指针的方法

这是我一开始写的,双指针逻辑应该是对的,但是退出循环的逻辑和判断条件之类的有点问题,说明我的代码实现功底还是有问题,相当有问题

  1. int minSubArrayLen(int target, vector<int>& nums) {
  2.         int start=0; int end=0;
  3.         int sum=0;
  4.         int len=100000;
  5.         while(start<nums.size() && end<=nums.size() && start<=end){
  6.             
  7.             if(sum<target){
  8.                 sum+=nums[end];
  9.                 cout<<"not enough: add "<< nums[end];
  10.                 end++;
  11.                 cout<<" (start, end)= "<<start<<" "<<end<<endl;
  12.                 cout<<"sum= "<<sum<<endl;
  13.             }
  14.             else{
  15.                 len=std::min(len,end-start);
  16.                 sum-=nums[start];
  17.                 cout<<"enough: deduct "<< nums[start];
  18.                 start++; 
  19.                 cout<<" (start, end)= "<<start<<" "<<end<<endl;
  20.                 cout<<"sum= "<<sum<<endl;
  21.             }
  22.         }
  23.         return (len==100000)?0:len;
  24.         
  25.     }

chatgpt给我改成了这样:

  1. int minSubArrayLen(int target, vector<int>& nums) {
  2.     int start = 0, end = 0, sum = 0, len = INT_MAX;
  3.     while (end < nums.size()) {
  4.         sum += nums[end++];
  5.         while (sum >= target) {
  6.             len = std::min(len, end - start);
  7.             sum -= nums[start++];
  8.         }
  9.     }
  10.     return (len == INT_MAX) ? 0 : len;
  11. }

补一句吐槽,挂着梯子用csdn是真的好卡

95 无算法,主要考察模拟过程+对代码的控制,说白了就是能否成功精准实现

不到10min出思路,剩下再花20min 自己实现+问gpt修改

自己实现的问题是,每一个方向进行完后,忘记做i 和 j的微调

  1. vector<vector<int>> generateMatrix(int n) {
  2. vector<vector<int>> vec(n, vector<int>(n, 0));
  3. int value=1;
  4. //4 while loop
  5. int i=0; int j=0;
  6. while(value<=n*n){
  7. //right
  8. while(j<n && vec[i][j]==0){
  9. vec[i][j]=value;
  10. value++;
  11. j++;
  12. }
  13. i++;
  14. j--;
  15. //down
  16. while(i<n && vec[i][j]==0){
  17. vec[i][j]=value;
  18. value++;
  19. i++;
  20. }
  21. i--;
  22. j--;
  23. //left
  24. while(j>=0 && vec[i][j]==0){
  25. vec[i][j]=value;
  26. value++;
  27. j--;
  28. }
  29. i--;
  30. j++;
  31. //up
  32. while(i>=0 && vec[i][j]==0){
  33. vec[i][j]=value;
  34. value++;
  35. i--;
  36. }
  37. i++;
  38. j++;
  39. }
  40. return vec;
  41. }

 这个是过了的,就是一开始我完全忘记写i-- , j++ 那些东西了

代码随想录的方法比我更robust,用了好几个值来精确定位,而不是用原来是不是0来判断

看了以后两个感想:

1.联想到二分法那里强调的,左开右闭 那种,一定要精确控制好,非常重要,就虽然我自己也能写出来题,但这种原则牢记在心 不容易出实现上的问题

2.这种题 精确实现真的非常重要,我能想出思路,但实现很有问题

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/341360
推荐阅读
相关标签
  

闽ICP备14008679号