《代码随想录》-数组

《代码随想录》-数组

  • 704.二分查找
  • 27.移除元素
    • 26.删除有序数组中的重复项
    • 80.删除有序数组中的重复项
  • 977.有序数组的平方
  • 209.长度最小的子数组
  • 59.螺旋矩阵II

704.二分查找

leetcode链接

《代码随想录》-数组_第1张图片

代码

  • 左闭右开写法
class Solution {
    public int search(int[] nums, int t) {
        int left = 0;
        int right = nums.length;
        while(left < right){
            int mid = (left+right)/2;
            if(t < nums[mid]){
                right = mid;
            }else if(t > nums[mid]){
                left = mid + 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}
  • 左闭右闭写法
class Solution {
    public int search(int[] nums, int t) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = (left+right)/2;
            if(t < nums[mid]){
                right = mid - 1;
            }else if(t > nums[mid]){
                left = mid + 1;
            }else{
                return mid;
            }
        }
        return -1;
    }
}

分析

  • 第一种写法是在[left,right)中找目标t,left = right时左闭右开区间不正确,所以循环条件为left
  • 第二种写法是在[left,right]种找目标t,左右边界都是闭区间,所以当left=right时区间也是合法的,所以循环条件为left<=right。更新边界时,不能把遍历过的mid作为边界。

27.移除元素

leetcode题目链接
《代码随想录》-数组_第2张图片

代码

class Solution {
    public int removeElement(int[] nums, int val) {
        int l = 0;
        for(int j = 0;j < nums.length;j++){
            if(nums[j] != val){
                nums[l++] = nums[j];
            }
        }
        return l;
    }
}

分析

  • 双指针法
    • 一个j指针指向需要遍历的原数组,遍历完所有数据。
    • 一个l指针指向需要更新数组的下标,理解为待插入位置。不是目标值的时候就插入进该位置。

类似题目:26.删除有序数组中的重复项

26.删除有序数组中的重复项

leetcode链接
《代码随想录》-数组_第3张图片

代码

class Solution {
    public int removeDuplicates(int[] nums) {
        int l = 1;
        for(int j = 1;j<nums.length;j++){
            if(nums[j] != nums[l-1]){
                nums[l++] = nums[j];
            }
        }
        return l;
    }
}
  • 此题指针从1开始,默认第一个元素添加到数组里了,所以j指针需要与i指针的前一个元素做比对。

80.删除有序数组中的重复项

leetcode链接
《代码随想录》-数组_第4张图片

代码

class Solution {
    public int removeDuplicates(int[] nums) {
        int l = 2;
        for(int j = 2;j < nums.length;j++){
            if(nums[j] != nums[l-2]){
                nums[l++] = nums[j];
            }
        }
        return l;
    }
}

总结:

  • 通过以上题目可以发现通解
    • 对于前k个数字,直接保留
    • 对于后面的任意数字,保留前提:与当前写入的位置前面的第k个元素进行比较,不相同则保留
  • 通解代码
class Solution{
    public int removeDuplicates(int[] nums){
        return process(nums,2);
    }
    public int process(int[] nums,int k){
        int l = k;
        for(int j = k;j<nums.length;j++){
            if(nums[j] != nums[l-k]){
                nums[l++] = nums[j];
            }
        }
        return l;
    }
}

977.有序数组的平方

leetcode链接
《代码随想录》-数组_第5张图片

代码

class Solution {
    public int[] sortedSquares(int[] nums) {
        int l = 0;
        int r = nums.length - 1;
        int[] arr = new int[nums.length];
        int a = arr.length - 1;
        while(l <= r){
            if(nums[l]*nums[l] > nums[r]*nums[r]){
                arr[a--] = nums[l]*nums[l];
                l++;
            }else{
                arr[a--] = nums[r]*nums[r];
                r--;
            }
        }
        return arr;
    }
}

分析

  • 两个指针分别指向头和尾,比较平方大小,添加到新数组。

209.长度最小的子数组

leetcode
《代码随想录》-数组_第6张图片

代码

  • 滑动窗口
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int length = Integer.MAX_VALUE;
        int i = 0;
        int sum = 0;
        for(int j = 0;j < nums.length;j++){
            sum += nums[j];
            while(sum >= target){
                int sublength = j - i+1;
                sum -= nums[i++];
                length = length < sublength ? length : sublength;
            }
        }
        return length == Integer.MAX_VALUE ? 0 : length;
    }
}

分析

  • 只用一个for循环,当sum大于等于目标值时,窗口就该缩小了。
  • 为什么是while不是if?
    • 因为当大于目标值的时候不止缩小1次
    • 例子:【1,1,1,1,1,7】,遍历完才大于等于7,如果是使用if,前一个指针移动1次就会结束。while看作循环版if。
  • 为什么是>=而不是>
    • 因为更新长度在while循环内,如果没有等于就不会进去更新长度了。

59.螺旋矩阵II

leetcode
《代码随想录》-数组_第7张图片

代码

class Solution {
    public int[][] generateMatrix(int n) {
        int startx = 0;
        int starty = 0;
        int loop = n;
        int offset = 1;
        int count = 1;
        int[][] arr = new int[n][n];
        while(loop / 2 > (offset-1)){
            int i = starty;
            int j = startx;
            for(;j < n - offset;j++){
                arr[starty][j] = count++;
            }
            for(;i < n - offset;i++){
                arr[i][j] = count++;
            }
            for(;j>offset-1;j--){
                arr[i][j] = count++;
            }
            for(;i>offset - 1;i--){
                arr[i][j] = count++;
            }
            offset++;
            startx++;
            starty++;
        }
        if(n % 2 == 1){
            arr[startx][starty] = count;
        }
        return arr;
    }
}

分析

  • 模拟正方形矩阵,注意边界条件,每次遍历都是左闭右开。

你可能感兴趣的:(代码随想录,java,leetcode,算法)