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;
}
};