#LeetCode每日打卡 --- day02 [ LeetCode.997 有序数组的平方 && LeetCode.189 旋转数组 ]

本文详细介绍了LeetCode上的两道数组操作题:有序数组的平方和旋转数组。对于有序数组的平方,提供了三种解法,包括直接平方后排序、双指针法以及从两端同时向中间逼近的策略,分析了各自的时间和空间复杂度。而对于旋转数组,通过数组翻转的方法实现元素的快速移动,同样给出了两种解决方案。文章总结了这些算法的关键点,便于读者理解掌握。
摘要由CSDN通过智能技术生成

       

目录

题目:

一、有序数组的平方

二、旋转数组

总结





题目

        LeetCode.997 有序数组的平方

        LeetCode.189 旋转数组





一、有序数组的平方

  1. 解题思路:
    1. 方法一:平方后直接排序
    2. 方法二:双指针
      1. 原数组按非递减顺序排列,因此,平方后负数按降序排列,非负数按升序排列;
      2. 找到整数与负数的分界线,便可得到两个有序的子数组;令负数与非负数的分界线为neg,即nums[0]到nums[neg]为负数,nums[neg+1]到nums[n-1]为非负数;平方后,nums[0]到nums[neg]降序排列,nums[neg+1]到nums[n-1]为升序排列;
      3. 使用归并排序:使用两个指针分别指向neg和neg+1,每次比较两个指针对应的数,较小的放入答案,并移动指针,继续比较。直至一侧移到边界,将另一侧未遍历的数全部放入。  
    3. 方法三:使用两个指针分别指向0和n-1,每次比较两指针对应的数,较大的逆序放入答案,并移动指针,继续比较。无需处理移至边界的情况。
  2. 代码:
    /* 1  */
    class Solution {
        public int[] sortedSquares(int[] nums) {
            int[] ans = new int[nums.length];
            for(int i = 0; i < nums.length; i++) {
                ans[i] = nums[i] * nums[i];
            }
            Arrays.sort(ans);
            return ans;
        }
    }
    /* 2  */
    class Solution {
        public int[] sortedSquares(int[] nums) {
            int n = nums.length;
            int neg = -1;
            //找分界线
            for(int i = 0; i < n; i++){
                if(nums[i] < 0)
                    neg = i;
                else
                    break;
            }
            
            int[] ans = new int[n];
            int index = 0, i = neg, j = neg + 1;
            //排序
            while(i >= 0 || j < n) { //两边都未出边界
                if(i < 0) { //全为非负数
                    ans[index] = nums[j] *nums[j];
                    ++j;
                } else if(j == n) { //全为负数
                    ans[index] = nums[i] *nums[i];
                    --i;
                } else if(nums[i] * nums[i] < nums[j] * nums[j]) { //选出小的放入结果
                    ans[index] = nums[i] * nums[i];
                    --i;
                } else {
                    ans[index] = nums[j] *nums[j];
                    ++j;
                }
                ++index;
            }
            return ans;
        }
    }
    /* 3 */
    class Solution {
        public int[] sortedSquares(int[] nums) {
            int n = nums.length;
            int[] ans = new int[n];
            for(int i = 0, j = n-1, index = n - 1; i <= j; ){
                if(nums[i] * nums [i] > nums[j] * nums[j]){ //选出大的放入结果
                    ans[index] = nums[i] * nums[i];
                    ++i;
                } else {
                    ans[index] = nums[j] * nums[j];
                    --j;
                }
                --index;
            }
            return ans;
        }
    }

3. 复杂度分析:

  • 方法一
    • 时间复杂度:O(nlogn)
    • 空间复杂度:O(logn),除了存储数组外,需要 O(logn) 的栈空间进行排序。
  • 方法二
    • 时间复杂度:O(n)
    • 空间复杂度:O(1),除了存储答案的数组O(n)外,只需要维护常量空间。
  • 方法三
    • 时间复杂度:O(n)
    • 空间复杂度:O(1),除了存储答案的数组O(n)外,只需要维护常量空间。

二、旋转数组

  1. 解题思路:
    1. 方法一:用新数组存储元素移动k位后的数组,再将其复制回原数组
    2. 方法二:数组翻转
      1. 元素移动k位后,尾部k%n位移到数组头部,其余向后移动k%n位;
      2. 可以将所有元素翻转,尾部元素就被移到了头部,翻转[0,k%n-1]区间和[k%n,n-1]区间得到答案;

  2. 代码
    /* 1 */
    class Solution {
        public void rotate(int[] nums, int k) {
            int n = nums.length;
            int[] ans = new int[n];
            k %= n;
            for(int i = 0; i < n; i++){
                ans[(i+k)%n] = nums[i];
            }
            System.arraycopy(ans, 0, nums, 0, n);
        }
    }
    /* 2 */
    class Solution {
        public void rotate(int[] nums, int k) {
            int n = nums.length;
            k = k % n;
            reverse(nums, 0, n - 1);
            reverse(nums, 0, k - 1);
            reverse(nums, k, n - 1);
        }
    
        public void reverse(int[] nums, int start, int end){
            while(start < end){
                //交换start和end
                int t = nums[start];
                nums[start++] = nums[end];
                nums[end--] = t;
            }
        }
    }
  3. 复杂度分析
    1. 时间复杂度:O(n)
    2. 空间复杂度:O(1)





总结

        想不到,我好废

  1. System.arraycopy(Object src,  int  srcPos, Object dest, int destPos, int length)

                src:要复制的数组 

                srcPos:要复制数的起始位置

                dest:目标数组

                destPos:目标数组的下标位置

                length:复制的个数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值