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

184 阅读3分钟

挑战LeetCode热题100(TS版本)

打卡第一天

1、两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

示例 2:

输入: nums = [3,2,4], target = 6
输出: [1,2]

示例 3:

输入: nums = [3,3], target = 6
输出: [0,1]

思路:暴力破解、二分查找、hash

暴力破解:

function twoSum(nums: number[], target: number): number[] {
  for(let i=0;i<nums.length;i++) {
    for(let j=i;j<nums.length;j++) {
      if(nums[i] + nums[j] === target) {
        return [i,j]
      }
    }
  }
  return [0,0]
}
  • 时间复杂度:O(nn)(n*n)
  • 空间复杂度:O(1)

二分查找:

function twoSum(nums: number[], target: number): number[] {
    if(nums.length === 2 && nums[0] + nums[1] === target) {
        return [0,1]
    }
    const sortedArr = [...nums].sort((a, b) => a - b); // 对数组进行排序
    let left = 0;
    let right = sortedArr.length - 1;

    while (left < right) {
        const sum = sortedArr[left] + sortedArr[right];

        if (sum === target) {
        // 找到两个数的和,获取它们在原始数组中的位置
        const index1 = nums.indexOf(sortedArr[left]);
        const index2 = nums.indexOf(sortedArr[right]);
        return [index1, index2];
        } else if (sum < target) {
            left++; // 和小于目标值,左指针右移
        } else {
            right--; // 和大于目标值,右指针左移
        }
    }

    return []; // 没有找到两个数的和,返回空数组
}
  • 时间复杂度:O(nlogin(n))(nlogin(n))
  • 空间复杂度:O(n)

Hash:

function twoSum(nums: number[], target: number): number[] {
    const map = new Map()
    for(let i=0;i<nums.length;i++) {
        const component = target - nums[i]
        if(map.has(component)) {
            return [map.get(component), i]
        }
        map.set(nums[i], i)
    }
    return []
}
  • 时间复杂度:O(n)(n)
  • 空间复杂度:O(1)

2、字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

思路:暴力破解、Hash

暴力破解:

function groupAnagrams(strs: string[]): string[][] {
    const result = []
    for(let i=0;i<strs.length;i++) {
       const a = [strs[i]]
       const bool = result.findIndex(item => item.includes(strs[i]))
       if(bool !== -1) {
           continue
       }
       for(let j=i+1; j<strs.length;j++) {
            if(strs[i].split('').sort().join() === strs[j].split('').sort().join()) {
                a.push(strs[j])
            }
       }
       result.push(a)
    }
    return result
};
  • 时间复杂度:O(nm)(n*m)
  • 空间复杂度:O(n*m)

Hash:

function groupAnagrams(strs: string[]): string[][] {
    const map = new Map()
    for(const str of strs) {
        const sortChar = str.sort()
        if(map.has(sortChar)) {
            map.get(sortChar).push(str)
        } else {
            map.set(sortChar, [str])
        }
    }
    return Array.from(map.values())
};
  • 时间复杂度:O(n)(n)
  • 空间复杂度:O(1)

3、最长连续序列

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) **的算法解决此问题。

示例 1:

输入: nums = [100,4,200,1,3,2]
输出: 4
解释: 最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

示例 2:

输入: nums = [0,3,7,2,5,8,4,6,0,1]
输出: 9

**思路: Hash1(排序、对比今后记录在Hash中) 、Hash2(寻找到最小的值,从最小值开始对比) **

Hash1:

function longestConsecutive(nums: number[]): number {
    const sortArr = nums.sort((a,b) => a - b)
    const map = new Map()
    let maxLength = 0
    for(let i=0;i< sortArr.length;i++) {
        map.set(sortArr[i], 1)
    }

    for(let i=0;i< sortArr.length;i++) {
        if(sortArr[i] + 1 === sortArr[i+1]) {
            const mp_pre = map.get(sortArr[i])
            const mp_next = map.get(sortArr[i+1])
            map.set(sortArr[i+1], mp_pre + mp_next)
        } else {
            continue
        }
    }

    for(let [key, value] of map) {
        if(value > maxLength) {
            maxLength = value
        }
    }

    return maxLength
};
  • 时间复杂度:O(nlogin(n))(n*login(n))
  • 空间复杂度:O(n)

Hash2:

function longestConsecutive(nums: number[]): number {
   const set = new Set()
   const maxLength = 0
   for(const n of nums) {
       set.add(n)
   }
   for(const s of set) {
          if(!set.has(s-1)) {
                let currentNum = s
                let currentLength = 1
                while(set.has(currentNum + 1)) {
                    currentNum=s+1
                    currentLength+=1
                }
                maxLength = Math.max(currentLength, maxLength)
          }
    }
    return maxLength
};
  • 时间复杂度:O(n)(n)
  • 空间复杂度:O(n)

总结一下: 上面三道题推荐用Hash解法。如有更好的解法欢迎评论,如有问题欢迎指正!