【力扣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;
    }
};
相关推荐
凌肖战1 小时前
力扣网C语言编程题:在数组中查找目标值位置之二分查找法
c语言·算法·leetcode
weixin_478689762 小时前
十大排序算法汇总
java·算法·排序算法
luofeiju2 小时前
使用LU分解求解线性方程组
线性代数·算法
学不动CV了2 小时前
数据结构---线性表理解(一)
数据结构
SKYDROID云卓小助手2 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
ysa0510303 小时前
数论基础知识和模板
数据结构·c++·笔记·算法
GEEK零零七3 小时前
Leetcode 1103. 分糖果 II
数学·算法·leetcode·等差数列
今天背单词了吗9803 小时前
算法学习笔记:7.Dijkstra 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·数据结构·笔记·算法
气质、小青年!3 小时前
【排序算法】
c语言·数据结构
重庆小透明4 小时前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存