13. <tag-数组和双指针(左右指针)>-lt.977-有序数组的平方 + lt.75-颜色分类

lt.977-有序数组的平方

[案例需求]
在这里插入图片描述

[思路分析]

  1. 简单题简单做, 遍历给定的有序数组的每个数, 把遍历到的每个数进行平方, 放入到新数组,
  2. 而由于题目要求我们输出的数组是有序的, 如果数组中含有负数, 那么还要对得到的结果数组进行排序后, 再返回.

[代码实现]

class Solution {
    
    
    public int[] sortedSquares(int[] nums) {
    
    
        //新数组. 存放平方数
        int[] res = new int [nums.length];
        int resIndex = 0;

        for(int i = 0; i < nums.length; i++){
    
    
            res[resIndex++] = nums[i] * nums[i];
        }

        //对数组排序
        Arrays.sort(res);

        return res;
    }
}

[优化1. 数组原地存储平方数, 减少创建新数组的内存]

class Solution {
    
    
    public int[] sortedSquares(int[] nums) {
    
    
        //新数组. 存放平方数
        //int[] res = new int [nums.length];
        //int resIndex = 0;

        for(int i = 0; i < nums.length; i++){
    
    
            nums[i] = nums[i] * nums[i];
        }

        //对数组排序
        Arrays.sort(nums);

        return nums;
    }
}
  • 效率稍微提高了一点点;
    在这里插入图片描述

[优化2. 左右双指针遍历数组, 每次比较前后双指针的平方数, 大的放入到数组后面]

  • [思路分析]

    • 题目给我们的原数组是非递减的, 如果数组中的数都是整数, 那无疑得到的平方数都是递增的,
    • 我们要考虑的是数组中含有负数时, 而且负数的绝对值如果比数组中靠后的数大的话, 那无疑平方数会出现前面的数大, 后面的数小;
    • 所以这里我们采用双指针, 左指针指向数组的开始, 右指针指向末尾,
    • 通过比较左右指针平方数的大小, 把较大的放到数组的末尾(注意,这里是把数组从后向前的索引赋值的)
    • 一定要明确的一点是, 原数组是非递减的(这就意味着平方数最大的要么在数组的最左边(负数), 要么在数组的最右边), 我们才能使用左右双指针;
  • [代码实现]

class Solution {
    
    
    public int[] sortedSquares(int[] nums) {
    
    
        
        int L = 0;
        int R = nums.length - 1;

        int[] res = new int[nums.length];
        int lastIndex = nums.length - 1;

        while(L <= R){
    
    
            int left = nums[L] * nums[L];
            int right = nums[R] * nums[R];

            if(left < right){
    
    
                res[lastIndex--] = right;
                R--;
            }else{
    
    
                res[lastIndex--] = left;
                L++;
            }
        }
        return res;
    }
}

在这里插入图片描述

lt.75-颜色分类

[案例需求]
1843143981

[思路分析]

  1. 题目大意: 将数组中的数按照 0->1->2的顺序排列, 其中0,1,2都是可重复的;
  2. 先说一句, 用Arrays.sort(nums)的, 等着感谢信吧(滑稽)
  3. 前面提过一嘴, 对于有序数组的, 加上或不加上原地修改数组的, 一定要考虑下是否能用双指针解题;
  4. 这道题, 我们应该想到用左右双指针, 但是左右双指针在这里是用来标注0和2的边界的, 我们还应用一个指针遍历做左右指针之间的数(从L->R), 所以, 这道题用三指针来解比较容易理解;
    • 定义指针 i, 遍历数组, 左指针 L, 标记0的右边界, 右指针R, 标记2的左边界
    • i 遍历数组, 从L–>R,
    • 遇到0的话, 与左指针L交换;
    • 遇到1的话, 不说话, 直接 i++;
    • 遇到2的话, 与右指针R交换;

这里一定要多体会下, 指针在不同初值上的差别;

[代码实现]

class Solution {
    
    
    public void sortColors(int[] nums) {
    
    

        // 0,1,2
        //左边0, 中间1, 右边2
        //左右指针
        int L = 0;
        int R = nums.length;
        int i = 0;

        while(i < R){
    
    
            if(nums[i] == 0){
    
    
                swap(i, L, nums);
                L++;
                i++;
            }else if(nums[i] == 1){
    
    
                i++;
            }else if(nums[i] == 2){
    
    
                 R--;
                swap(i, R, nums);
               
            } 
        }
        
    }

    public void swap(int l, int r, int[] nums){
    
    
        int temp = nums[l];
        nums[l] = nums[r];
        nums[r] = temp;
    }
}

在这里插入图片描述

Guess you like

Origin blog.csdn.net/nmsLLCSDN/article/details/121791280