训练营第二天

      

  • 力扣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;
      }

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值