前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《LeetCode热题100》---<5.②普通数组篇五道>

《LeetCode热题100》---<5.②普通数组篇五道>

作者头像
用户11288958
发布2024-09-24 15:20:56
610
发布2024-09-24 15:20:56
举报
文章被收录于专栏:用户11288958的专栏

本篇博客讲解LeetCode热题100道普通数组篇中的五道题 第三道:轮转数组(中等) 第四道:除自身以外数组的乘积(中等)

第三道:轮转数组(中等)

方法一:使用额外的数组

代码语言:javascript
复制
class Solution {
    public void rotate(int[] nums, int k) {
        int len = nums.length;
        int[] newArr = new int[len];
        for (int i = 0; i < len; ++i) {
            newArr[(i + k) % len] = nums[i];
        }
        System.arraycopy(newArr, 0, nums, 0, len);
    }
}

1.新建一个nums数组长度的数组。 2.轮转k次。因此我们将从(i + k) % len开始,将nums数组中的值依次赋值给新数组。 3.最终将新数组中的值拷贝回原来的数组。 时间复杂度: O(n),其中 n 为数组的长度。 空间复杂度: O(n)。

方法二:数组翻转

代码语言:javascript
复制
​​​​​​class Solution {
    public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }

    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start += 1;
            end -= 1;
        }
    }
}

翻转的思想:轮转k个位置,那么也就相当于先将数组翻转。之后再翻转(0,k-1)这个位置的元素。再翻转(k,n-1)这个位置的元素。下如图演示。

第四道:除自身以外数组的乘积(中等)

方法一:前缀之积乘以后缀之积

代码语言:javascript
复制
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int length = nums.length;

        // L 和 R 分别表示左右两侧的乘积列表
        int[] L = new int[length];
        int[] R = new int[length];

        int[] answer = new int[length];

        // L[i] 为索引 i 左侧所有元素的乘积
        // 对于索引为 '0' 的元素,因为左侧没有元素,所以 L[0] = 1
        L[0] = 1;
        for (int i = 1; i < length; i++) {
            L[i] = nums[i - 1] * L[i - 1];
        }

        // R[i] 为索引 i 右侧所有元素的乘积
        // 对于索引为 'length-1' 的元素,因为右侧没有元素,所以 R[length-1] = 1
        R[length - 1] = 1;
        for (int i = length - 2; i >= 0; i--) {
            R[i] = nums[i + 1] * R[i + 1];
        }

        // 对于索引 i,除 nums[i] 之外其余各元素的乘积就是左侧所有元素的乘积乘以右侧所有元素的乘积
        for (int i = 0; i < length; i++) {
            answer[i] = L[i] * R[i];
        }

        return answer;
    }
}

1.新建一两个数组长度为nums的长度。一个L存前缀之积,一个R存后缀之积 2.L[i] 表示索引 i 左侧所有元素的乘积,因为索引为 '0' 的元素左侧没有元素, 所以 L[0] = 1 3.for循环从1开始,计算每个元素的前缀之积 L[i] = nums[i - 1] * L[i - 1]; 4.再从后往前遍历计算后缀之积。R[length - 1] = 1;。R[i] = nums[i + 1] * R[i + 1];得到后缀之积。 5. for (int i = 0; i < length; i++) { answer[i] = L[i] * R[i]; } 6.最终返回answer。

时间复杂度:O(N),其中 N 指的是数组 nums 的大小。预处理 L 和 R 数组以及最后的遍历计算都是 O(N) 的时间复杂度。 空间复杂度:O(N),其中 N 指的是数组 nums 的大小。使用了 L 和 R 数组去构造答案,L 和 R 数组的长度为数组 nums 的大小

方法二:方法一的进阶,空间复杂度 O(1) 的方法

代码语言:javascript
复制
class Solution {
    public int[] productExceptSelf(int[] nums) {
        int length = nums.length;
        int[] answer = new int[length];

        // answer[i] 表示索引 i 左侧所有元素的乘积
        // 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1
        answer[0] = 1;
        for (int i = 1; i < length; i++) {
            answer[i] = nums[i - 1] * answer[i - 1];
        }

        // R 为右侧所有元素的乘积
        // 刚开始右边没有元素,所以 R = 1
        int R = 1;
        for (int i = length - 1; i >= 0; i--) {
            // 对于索引 i,左边的乘积为 answer[i],右边的乘积为 R
            answer[i] = answer[i] * R;
            // R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上
            R *= nums[i];
        }
        return answer;
    }
}

1.新建一个answer数组长度为nums的长度。 2.answer[i] 表示索引 i 左侧所有元素的乘积,因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1 3.for循环从1开始,计算每个元素的前缀之积answer[i] = nums[i - 1] * answer[i - 1]; 4.再从后往前遍历计算后缀之积。R 为右侧所有元素的乘积。开始R=1。从n-1开始遍历。令 answer[i] = answer[i] * R;得到最终答案。R *= nums[i];得到后缀之积。 5.最终返回answer。

时间复杂度:O(N),其中 N 指的是数组 nums 的大小。分析与方法一相同。 空间复杂度:O(1),输出数组不算进空间复杂度中,因此我们只需要常数的空间存放变量。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第三道:轮转数组(中等)
    • 方法一:使用额外的数组
      • 方法二:数组翻转
      • 第四道:除自身以外数组的乘积(中等)
        • 方法一:前缀之积乘以后缀之积
          • 方法二:方法一的进阶,空间复杂度 O(1) 的方法
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档