【力扣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;
    }
};
相关推荐
小智学长 | 嵌入式8 分钟前
进阶-数据结构部分:2、常用排序算法
java·数据结构·算法
少了一只鹅8 分钟前
字符函数和字符串函数
c语言·算法
Dr.9271 小时前
1-10 目录树
java·数据结构·算法
双叶8361 小时前
(C语言)超市管理系统 (正式版)(指针)(数据结构)(清屏操作)(文件读写)(网页版预告)(html)(js)(json)
c语言·javascript·数据结构·html·json
子豪-中国机器人1 小时前
C++ 蓝桥 STEMA 省选拔赛模拟测试题(第一套)
开发语言·c++·算法
callJJ1 小时前
Bellman - Ford 算法与 SPFA 算法求解最短路径问题 ——从零开始的图论讲解(4)
数据结构·算法·蓝桥杯·图论·单源最短路径·bellman- ford算法
圈圈编码1 小时前
LeetCode Hot100刷题——轮转数组
java·算法·leetcode·职场和发展
金融小师妹6 小时前
应用BERT-GCN跨模态情绪分析:贸易缓和与金价波动的AI归因
大数据·人工智能·算法
广州智造6 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
Trent19858 小时前
影楼精修-肤色统一算法解析
图像处理·人工智能·算法·计算机视觉