二十天刷leetcode【hot100】算法- day1[前端Typescript]

哈希表

其他语言版本

js-day1
go-day1
python-day1

1. 两数之和

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

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。你可以按任意顺序返回答案。
在这里插入图片描述

链接

题解

该题目的关键在于遍历循环数组,在遍历的过程中,记录目前值与target的差值,且使用map记录差值情况,若存在差值,则直接返回差值

function twoSum(nums: Array<number>, target: number) {
  const len = nums.length;
  const hashMap = new Map();
  for(let i = 0; i < len; i++) {
      // 计算当前值与target的差值
      const targetNew = target - nums[i];
      if (hashMap.has(targetNew)) {
          // 如果存在该差值,则直接返回 [该差值的下标, 与当前值的下标]
          return [hashMap.get(targetNew), i];
      } else {
          // 暂时不存在差值,存入当前值的下标
          hashMap.set(nums[i], i);
      }
  }
};

// const arr = twoSum([3,2,4], 6);
// console.log({ arr });

2. 字母异位词分组

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

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
在这里插入图片描述

链接

题解

该题目在于将每一项数据根据Unicode编码排序,异位词经过排序后的字符串会相等,后使用map记录数据即可。

function groupAnagrams(strs: string[]): string[][] {
  const len = strs.length;
  // 讲异位词归类成一个数组 {'ab': ['ab', 'ba']}
  const hashMap = new Map<string, string[]>();
  // 遍历字符串数组
  for(let i = 0; i < len; i++) {
      const temp = strs[i];
      // 字符串转化为数组 ['b', 'a']
      const newStr = (Array.from(temp) as string[])
                      // 按Unicode编码排序 ['a', 'b']
                      .sort((a, b) =>  a.charCodeAt(0) - b.charCodeAt(0))
                      // 拼接成字符串 ['ab']
                      .reduce((a, b) => `${a}${b}`, '');
      if (hashMap.has(newStr)) {
          // 如果存在异位词,则推进数组
          (hashMap.get(newStr) || []).push(temp);
      } else {
          // 不存在异位词,则set初始化数组
          hashMap.set(newStr, [temp]);
      }
  }
  const res: string[][] = [];
  // 输出结果
  hashMap.forEach((value) => {
      res.push(value);
  });
  return res;
};

// const arr = groupAnagrams(['abc', 'cab', 'de', 'ed']);
// // { arr: [ [ 'abc', 'cab' ], [ 'de', 'ed' ] ] }
// console.log({ arr });

3.最长连续序列

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

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
在这里插入图片描述
链接

题解:

在这里插入图片描述

function longestConsecutive(nums: number[]): number {
  // 去重 [100, 4, 4, 200, 1, 3, 2] => [100, 4, 200, 1, 3, 2]
  let num_set: Set<number> = new Set([...nums]);
  // 记录当前最长连续序列长度
  let longestStreak = 0;

  for (const num of num_set) {
      // 遍历
      if (!num_set.has(num - 1)) {
          // 如果不存在比当前值小1的值,则当前值作为起点
          // 如100, 1可以作为起点
          let currentNum = num;
          // 记录当前最长连续序列长度
          let currentStreak = 1;

          while (num_set.has(currentNum + 1)) {
              // 遍历,找比当前值大1的数
              currentNum += 1;
              currentStreak += 1;
          }
          // 更新最大长度
          longestStreak = Math.max(longestStreak, currentStreak);
      }
  }

  return longestStreak;   
};

// const num = longestConsecutive([100, 4, 4, 200, 1, 3, 2]);
// // { num: 4 }
// console.log({ num });

指针

4.移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。
在这里插入图片描述

链接

题解

在这里插入图片描述

// 快排思想
function moveZeroes(nums: Array<number>) {
  if (nums.length === 1) {
    return nums;
  }
  let left = 0;
  for (let right = 0; right < nums.length; right++) {
    if (nums[right] !== 0) {
      // 右边不等于0
      if (nums[left] === 0) {
          // 左边等于0
          [nums[right], nums[left]] = [nums[left], nums[right]];
      }
      // 找到了右边不等于0的目标元素,移动左指针寻找等于0的元素
      left++;
    }
  }
  return nums;
};

// const arr = moveZeroes([0, 1, 0, 3, 12]);
// // { num: 4 }
// console.log({ arr });

5.盛水最多的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。

说明:你不能倾斜容器。
在这里插入图片描述

链接

题解

左右指针法,每次移动短的指针能才有机会使容纳的水变多,因为左右指针收窄时,形成的容器的底是变小的,而能存多少水,容器的高也是一个决定性因素,根据木桶原理,短的木板决定水桶能装多少水,在底变小的情况下,移动短的指针有机会遇到更长的木板,使得容积变大。移动过程中,更新最大值即可。

function maxArea(height: Array<number>): number {
  let left = 0, right = height.length - 1;
  let res = 0;
  while(left < right) {
      // 底
      const bottom = right - left;
      // 高
      const h = Math.min(height[left], height[right]);
      // 更新最大值
      res = Math.max(res, bottom * h);
      if (height[left] > height[right]) {
          // 右边小,移动小的
          right--;
      } else {
          // 左边小,移动小的
          left++;
      }
  }
  return res;
};

// const num = maxArea([1, 8, 6, 2, 5, 4, 8, 3, 7]);
// // { num: 49 }
// console.log({ num });

关注我的公众号,回复 100905A1 获取hot100算法在线链接
在这里插入图片描述

  • 20
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值