Day2 数据结构与算法(Java)----数组(双指针),滑动窗口

一,题977. 有序数组的平方(双指针法)

题目链接:
力扣

给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

可以考虑双指针法,i指向起始位置,j指向终止位置。

定义一个新数组result,和A数组一样的大小,让k指向result数组终止位置。

如果A[i] * A[i] < A[j] * A[j] 那么result[k--] = A[j] * A[j]; 。

如果A[i] * A[i] >= A[j] * A[j] 那么result[k--] = A[i] * A[i];

class Solution {
    public int[] sortedSquares(int[] nums) {
    int left=0;
    int right=nums.length-1;
    int k=nums.length-1;
    int [] result=new int[nums.length];
    while(left<=right)
    {
        if(nums[left]*nums[left]

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第1张图片

其中

     result[k]=nums[right]*nums[right];
            right--;
            k--;

 可以简写为如下代码

result[k--]=nums[right]*nums[right--];

二,209.长度最小的子数组

题目链接:

力扣

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

在本题中实现滑动窗口,主要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口就是 满足其和 ≥ s 的长度最小的 连续 子数组。

窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
    int left=0;
     int result =Integer.MAX_VALUE;
    int sum=0;
    for(int right=0;right=target)
     {
         int length=right-left+1;
         result = Math.min(result, length);
         sum-=nums[left++];
     }
    }
   return result ==Integer.MAX_VALUE? 0 : result;
    }
}

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第2张图片

Integer.MAX_VALUE表示int数据类型的最大取值数:2 147 483 647
Integer.MIN_VALUE表示int数据类型的最小取值数:-2 147 483 648

补充:
Integer.MAX_VALUE+1=Integer.MIN_VALUE

因为:
Integer.MAX_VALUE的二进制是0111 1111 1111 1111 1111 1111 1111 1111
Integer.MIN_VALUE的二进制是 1000 0000 0000 0000 0000 0000 0000 0000

0111 1111 1111 1111 1111 1111 1111 1111+1=1000 0000 0000 0000 0000 0000 0000 0000

其中Integer.MAX_VALUE可以换成一个较大的值,如99999999。

最后一行不能删除,否则报错,分析一下这种情况:

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第3张图片

此时永远不会满足 while(sum>=target),直接遍历完数组,不会执行while语句中的值,result的值还是之前默认的那个很大的数。而实际上没有找到满足的子数组result应该返回0。所以最后不能直接返回result,而是

return result ==Integer.MAX_VALUE? 0 : result;

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第4张图片

以下三种写法都是等效的

 result = Math.min(result, length);
 result = (result
if(result>length) result=length;

最后,不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。像上面那种极端的情况下直接不进入到while中,只被操作一次,时间复杂度是  n,也就是O(n)。

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第5张图片

三,59.螺旋矩阵II(注意保持左闭右开区间原则)

题目链接:力扣

本题依然是要坚持循环不变量原则。

模拟顺时针画矩阵的过程:

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上

由外向内一圈一圈这么画下去。

class Solution {
    public int[][] generateMatrix(int n) {
    int [][]nums=new int[n][n];
    int start=0;
    int count=1;
    int loop=0;
    int i,j;
    while(loop++=loop;j--)
     nums[i][j]=count++;
     for(;i>=loop;i--)
     nums[i][j]=count++;
     start++;
    }
    if(n%2==1)
    {
     nums[start][start]=count;
    }
    return nums;
    }
}

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第6张图片

注意: while(loop++中的loop++不能放到循环末尾,也不能直接改成++loop,否则会报错;

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第7张图片

可改为

while(++loop<=n/2)

也可以直接放在循环的第一行

while(loop

 但是改为下面这样会报错

 while(loop<=n/2)
    {
          ++loop;
.....
}

加入输出语句,可以看出运行过程。可以看到多了一次循环,但是下标已经不对了,start变为了2,应该是nums[1][1]=9(即nums[start][start]=9)

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第8张图片

正确的运行结果如下:

Day2 数据结构与算法(Java)----数组(双指针),滑动窗口_第9张图片

你可能感兴趣的:(leetcode题库,leetcode,数据结构,算法)