兜兜零元 发表于 2025-1-15 22:39:48

LeetCode —— 数组

一、二分查找

定义 target 是在一个在左闭右开的区间里:


[*]while (left < right),这里利用 < ,由于left == right在区间[left, right)是没故意义的
[*]if(nums > target) right 更新为middle,由于当前nums不等于target,去左区间继承探求,而探求区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比力nums。
class Solution {
    public int search(int[] nums, int target) {
      int left = 0, right = nums.length;
      while (left < right) {
            int mid = left + ((right - left) >> 1);
            if (nums == target) {
                return mid;
            }
            else if (nums < target) {
                left = mid + 1;
            }
            else { // nums > target
                right = mid;
            }
      }
      // 未找到目标值
      return -1;
    }
}
提示:以下是本篇文章正文内容,下面案例可供参考
二、27. 移除元素

双指针法

双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针:


[*]快指针:探求新数组的元素 ,新数组就是不含有目标元素的数组
[*]慢指针:指向更新 新数组下标的位置
class Solution {
    public int removeElement(int[] nums, int val) {
      int left = 0;
      int right = nums.length - 1;
      while(left <= right){
            if(nums == val){
                nums = nums;
                right--;
            }else {
                // 这里兼容了right指针指向的值与val相等的情况
                left++;
            }
      }
      return left;
    }
}
三、977.有序数组的平方

双指针法



[*]数组实在是有序的, 只不外负数平方之后大概成为最大数了。
[*]那么数组平方的最大值就在数组的两头,不是最左边就是最右边,不大概是中心。
[*]此时可以思量双指针法了,i指向起始位置,j指向终止位置。
[*]定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。
class Solution {
    public int[] sortedSquares(int[] nums) {
      int left = 0, right = nums.length - 1;
      int[] result = new int;
      // 新数组的指针,从大到小填数据
      int index = nums.length - 1;

      // 双指针思想
      while(left <=right){
            if(nums * nums < nums * nums){
                result = nums * nums;
                right--;
            } else {
                result = nums * nums;
                left++;
            }
      }
      return result;
    }
}
四、209. 长度最小的子数组

滑动窗口



[*]如果只用一个for循环来表现滑动窗口的起始位置,那么如何遍历剩下的终止位置?此时难免再次陷入 暴力解法的怪圈。所以 只用一个for循环,那么这个循环的索引,一定是表现滑动窗口的终止位置。
[*]在本题中实现滑动窗口,重要确定如下三点:
[*]窗口内是什么? 如何移动窗口的起始位置? 如何移动窗口的结束位置?
[*]窗口就是满足其和 ≥ s 的长度最小的连续子数组。
[*]窗口的起始位置如何移动:如果当前窗口的值大于等于s了,窗口就要向前移动了(也就是该缩小了)。
[*]窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
      // 1. 初始化起始位置,数组和, 最终数组长度
      int i = 0, sum = 0, result = Integer.MAX_VALUE;
      // 2. 确定起始位置
      for(int j = 0; j <= nums.length - 1; j++){
            sum += nums;
            while(sum >= target){
                result = Math.min(result, j - i + 1);
                sum = sum - nums;
                i++;
            }
      }
      return result == Integer.MAX_VALUE ? 0 : result;
    }
}
五、59. 螺旋矩阵Ⅱ

循环不变量原则



[*]模仿顺时针画矩阵的过程(左闭右开):
[*]填充上行从左到右
[*]填充右列从上到下
[*]填充下行从右到左
[*]填充左列从下到上
class Solution {
    public int[][] generateMatrix(int n) {
      int[][] nums = new int;
      int startX = 0, startY = 0; //每圈起点
      int offset = 1;
      int count = 1;//矩阵中要填写的数字
      int loop = 1;   //记录当前的圈数
      int i,j;    //j代表列,i代表行

      while(loop <= n / 2){

            //顶部
            //左闭右开,所以判断循环结束时,j不能等于n-offset
            for(j = startY; j < n - offset; j++){
                nums = count++;
            }

            //右列
            //左闭右开,所以判断循环结束时,i不能等于n-offset
            for(i = startX; i < n - offset; i++){
                nums = count++;
            }

            //底部
            //左闭右开,所以判断循环结束时,j != startY
            for(; j > startY; j--){
                nums = count++;
            }

            //左列
            //左闭右开,所以判断循环结束时,i != startX
            for(; i > startX; i--){
                nums = count++;
            }

            startX++;
            startY++;
            offset++;
            loop++;
      }

      if(n % 2 == 1){
            nums = count;
      }
      return nums;

    }
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: LeetCode —— 数组