挑战LeetCode热题100(TS版本)打卡第五天

74 阅读3分钟

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

总结: