训练营第二天

      

  • 力扣977 有序数组的平方
    • 上来一看这道题就想着直接都平方 完后冒泡排序   不过暴力也算是成功了,时间复杂度是O(n+nlogn)
    • 接下来看到提示说用双指针, 由于惯性思维,只想着在原地操作,没想到malloc一个result,(可怜兮兮)。 二刷感觉就是有时候看视频听到卡哥的一句话就会醍醐灌顶。完后接下来又犯了错误。下面是犯错误的代码:看起来是不是很正确呢?但其实是不对的,我个人想到错误的就是最后剩下一个元素时,他其实属于第三种情况,完后在这个中会出现两次result[size--]   size 出现了负数,这是绝对有错的。
    • while (left <= right) {
              int L = nums[left] * nums[left];
              int R = nums[right] * nums[right];
              if (L > R) {
                  result[size--] = L;
                  left++;
              }
              else if (R > L) {
                  result[size--] = R;
                  right--;
              }
              else {
                  result[size--] = R;
                  result[size--] = L;
                  left++;
                  right--;
              }
          }

  • 正确的:   
    • while (left <= right) {
              int L = nums[left] * nums[left];
              int R = nums[right] * nums[right];
              if (L > R) {
                  result[size--] = L;
                  left++;
              }
              else{
                  result[size--] = R;
                  right--;
              }
              
          }

      Ps: 正好今天用了强制类型转换,记个笔记,也是今天课上学到的,有时候我们不管用不用强制类型转换,题都可以过,这是因为我们动态分配的是简单地空间(比如是int, char等) 但如果是结构或者更复杂的东西,系统就不知道你这一堆东西到底属于什么,所以强制类型转换,就告诉系统这是一个结构。pps: 可以利用这道题练一下十大排序算法               

  •  力扣209: 长度最小的子数组
    • 很熟悉很熟悉 就是在某一处感觉忘记了具体怎么操作, 难受
    • 滑动窗口  类似于双指针 。取两个指针之间的内容
    • 精髓 : 如何移动起始位置  什么时候移动起始位置? :   
    • if 还是 while   1,1,1,1,1,1,1,100  target 100 
    • 下面是自己写的错误示范
      int minSubArrayLen (int target, int* nums, int numsSize) {
          int sum = 0;
          int i = 0, j = 0;
          int minLen = INT_MAX;
          while (j < numsSize) {
              if (sum >= target) {
                  minLen = fmin(j - i, minLen);
                  sum -= nums[i];
                  i++;
              }
              sum += nums[j++];
          }
          if (sum >= target) {
                  minLen = fmin(j - i, minLen);
              }
          return minLen == INT_MAX ? 0 : minLen;
      }
  • 正确代码
    int minSubArrayLen (int target, int* nums, int numsSize) {
        int sum = 0;
        int i = 0, j = 0;
        int minLen = INT_MAX;
        for (; j < numsSize; j++) {
            sum += nums[j];
            while (sum >= target) {
                minLen = fmin(minLen, j - i + 1);
                sum -= nums[i++];
            }
        }
        return minLen == INT_MAX ? 0 : minLen;
    }
  •  感悟:
    • 1. 滑动窗口 ,用for循环去定义末位置 ,在用while不断更新初始位置这里的while很重要,因为  1,1,1,1,1,1,1,100  target 100 这样的情况需要不断地更新长度。
    • 2. return 的时候一定要判断是否找到或者是没找到
    • j - i + 1 是滑动窗口的长度 这其实就是因为数组起始位置是 0  从0 到3 其实是四个元素
  • 力扣螺旋矩阵 59
    • 难 没有思路
    • 关键: 边界上的点的归属  同样,我们还是需要一个东西“循环不变量” 每条边是左闭右闭呢还是左闭右开呢?处理第一个而不处理最后一个 
    • 为什么循环是 n / 2  这是因为每次循环只要两条边被占
    • 定义 : startx = 0, starty = 0 offset 用来控制边界
    • int** generateMatrix(int n, int* returnSize, int** returnColumnSizes){
          *returnSize = n;
          *returnColumnSizes = (int*)malloc(sizeof(int) * n);
          int** result = (int**)malloc(sizeof(int*) * n);
          for (int i = 0; i < n; i++){
              result[i] = (int*)malloc(sizeof(int) * n);
              (*returnColumnSizes)[i] = n; 
          }
          int startx = 0, starty = 0; // 定义没循环一个圈的起始位置
          int loop = n / 2; // 循环的圈数
          int mid = n / 2; //矩阵中间的位置
          int count = 1;  // 赋值器
          int offset = 1; //需要控制每条边的遍历长度 每次循环右边界收缩一位
          int i, j;
          while (loop--) {
              i = startx;
              j =starty;
              for (; j < n - offset; j++) {
                  result[startx][j] = count++;
              }
              for (; i < n - offset; i++) {
                  result[i][j] = count++;
              }
              for (; j > starty; j--) {
                  result[i][j] = count++;
              }
              for (; i > startx; i--) {
                  result[i][j] = count++;
              }
              startx++;
              starty++;
              offset++;
          }
          if (n % 2 == 1) result[mid][mid] = count;
          return result;
      }

      这道题和大一学年计算机导论机试题很像, 都是一些不涉及算法题,但是很考验代码功底的题型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第二十二天的算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,使得子数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二天的算法训练营的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值