【力扣Hot 100】普通数组2

3. 轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k **个位置,其中 k **是非负数。

示例 1:

复制代码
输入: nums = [1,2,3,4,5,6,7], k = 3
输出:[5,6,7,1,2,3,4]解释:
向右轮转 1 步:[7,1,2,3,4,5,6]
向右轮转 2 步:[6,7,1,2,3,4,5]
向右轮转 3 步:[5,6,7,1,2,3,4]

示例 2:

复制代码
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:

  • 1 <= nums.length <= 105
  • 231 <= nums[i] <= 231 - 1
  • 0 <= k <= 105

题解

使用反转数组的方法。

别人的解答:

kotlin 复制代码
nums = "----->-->"; k =3
result = "-->----->";

reverse "----->-->" we can get "<--<-----"
reverse "<--" we can get "--><-----"
reverse "<-----" we can get "-->----->"
this visualization help me figure it out :)

看图就能理解了。

反转数组可以定义两个指针bg, ed,一个指向数组开始,一个指向数组末尾,交换它们直到重合或相交。

cpp 复制代码
class Solution {
public:
    void reverse(vector<int>& nums, int bg, int ed) {
        while(bg < ed) {
            swap(nums[bg], nums[ed]);
            bg ++;
            ed --;
        }
    }
    void rotate(vector<int>& nums, int k) {
        int n = nums.size();
        k %= n;
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }
};

4. 除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。

请 **不要使用除法,**且在 O(n) 时间复杂度内完成此题。

示例 1:

复制代码
输入: nums =[1,2,3,4]输出:[24,12,8,6]

示例 2:

复制代码
输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

提示:

  • 2 <= nums.length <= 105
  • 30 <= nums[i] <= 30
  • 输入 保证 数组 answer[i]32 位 整数范围内

**进阶:**你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)

题解

非常明显的做法是建立一个前缀积数组,一个后缀积数组。输出的时候输出它们的乘积即可。

前缀积数组 f[i],表示以 i - 1 结尾的前缀积

后缀积数组 g[i],表示以 i + 1 结尾的后缀积

那么 f[i + 1] = f[i] * nums[i] , g[i - 1] = g[i] * nums[i]

cpp 复制代码
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> f(n + 1), g(n + 1);
        f[0] = 1;
        g[n - 1] = 1;
        for(int i = 0; i < n; i ++ ) {
            f[i + 1] = f[i] * nums[i];
        }
        for(int i = n - 1; i > 0; i -- ) {
            g[i - 1] = g[i] * nums[i];
        }
        
        vector<int> ans(n);
        for(int i = 0; i < n; i ++ ) {
            ans[i] = f[i] * g[i];
        }
        return ans;
    }
};

由于输出数组不计入空间复杂度,所以还可以继续优化。先把输出数组当作 L 数组来计算,然后再动态构造 R 数组得到结果。

cpp 复制代码
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int n = nums.size();
        vector<int> ans(n);
        ans[0] = 1;
        for(int i = 1; i <= n; i ++ ) {
            ans[i] = ans[i - 1] * nums[i - 1];
        }

        int r = 1;
        for(int i = n - 1; i >= 0; i --) {
            ans[i] = ans[i] * r;
            r *= nums[i];
        }

        return ans;
    }
};
相关推荐
雾月5518 分钟前
LeetCode 1292 元素和小于等于阈值的正方形的最大边长
java·数据结构·算法·leetcode·职场和发展
Pasregret38 分钟前
访问者模式:分离数据结构与操作的设计模式
数据结构·设计模式·访问者模式
OpenC++1 小时前
【C++QT】Buttons 按钮控件详解
c++·经验分享·qt·leetcode·microsoft
知来者逆2 小时前
计算机视觉——速度与精度的完美结合的实时目标检测算法RF-DETR详解
图像处理·人工智能·深度学习·算法·目标检测·计算机视觉·rf-detr
阿让啊2 小时前
C语言中操作字节的某一位
c语言·开发语言·数据结构·单片机·算法
এ᭄画画的北北2 小时前
力扣-160.相交链表
算法·leetcode·链表
草莓啵啵~2 小时前
搜索二叉树-key的搜索模型
数据结构·c++
爱研究的小陈3 小时前
Day 3:数学基础回顾——线性代数与概率论在AI中的核心作用
算法
渭雨轻尘_学习计算机ing3 小时前
二叉树的最大宽度计算
算法·面试
丶Darling.3 小时前
26考研 | 王道 | 数据结构 | 第八章 排序
数据结构·考研·排序算法