挑战LeetCode热题100(TS版本)
打卡第五天
数组的处理
1.轮转数组
给定一个整数数组 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]
思路一:借助额外的数组
注意:有个小坑,当k > nums.length 时不用重复翻转只需:k % nums.length
/**
Do not return anything, modify nums in-place instead.
*/
function rotate(nums: number[], k: number): void {
const c = [...nums]
const n = nums.length
k = k % nums.length
if(k === 0) return
for(let i=0;i<nums.length;i++) {
const l = i - k
if(l < 0) {
l = Math.abs(l) + 1
}
nums[l] = c[i]
}
};
思路二:翻转数组
由于是右转轮,所以方向应该是数组尾部翻转到数组首部,数组首部需要翻转尾部,所以按照以下步骤即可实现:
- 1、翻转整个数组 (尾部翻转到了首部)
- 2、翻转数组中前k个字符 (调整首部翻转位置)
- 3、翻转书中从k -> n 个字符 (尾部保持一开始的顺序)
Do not return anything, modify nums in-place instead.
*/
function rotate(nums: number[], k: number): void {
const n = nums.length
reverse(nums,0,n-1)
reverse(nums,0,k-1)
reverse(nums,k,n-1)
};
function reverse(nums: number[],i,j) {
while(i < j) {
const c = nums[i]
nums[i] = nums[j]
nums[j] = c
i++
j--
}
}
2.除自身以外数组的乘积
给你一个整数数组 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]
进阶: 你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)
思路一: 在使用除法的条件下,切保证时间复杂度O(n),我们要借助额外的数组来存储每个元素左侧的乘积和右侧的乘积,然后求两者乘积即可。
function productExceptSelf(nums: number[]): number[] {
const n = nums.length
const left = new Array(n)
const right = new Array(n)
left[0] = 1
right[n-1] = 1
// 求每个元素左侧的乘积,从第二个开始
for(let i=1;i<n;i++) {
left[i] = left[i-1] * nums[i-1]
}
// 求每个元素右侧的乘积,从倒数第二个开始
for(let i=n-2;i>=0;i--) {
right[i] = right[i+1] * nums[i+1]
}
for(let i=0;i<n;i++) {
nums[i] = left[i] + right[i]
}
return nums
};
思路二:进阶版; 要做到空间复杂度O(1),借助输出数组先存储每个元素的左侧值,然后再求乘每个元素右侧值
function productExceptSelf(nums: number[]): number[] {
const n = nums.length
const reuslt = new Array(n)
let leftValue = 1
for(let i=0;i<n;i++) {
result[i] = leftValue
leftValue*=nums[i]
}
let rightValue = 1
for(let i=n-1;i>=0;i--) {
result[i]*=rightValue
rightValue*=nums[i]
}
return reuslt
};
总结:
- 有关数组的算法操作推荐一下刷题路线:代码随想录数组部分。如有问题,欢迎指正!