【力扣hot100】day1

博主开始整理LeetCode热门100题的解法,涵盖两数之和、两数相等、最长无重复字符子串等9道题目。解题策略包括双指针、排序、哈希表和递归,例如两数之和问题采用排序后双指针法,无重复字符子串使用滑动窗口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

听从同事姐姐的建议,从今天开始,我将整理力扣hot100题的解法,不论简单困难,按顺序记录。

目录

1、两数之和

题目内容

题解

2、两数相等

题目内容

题解

3、无重复字符的最长子串

题目内容

题解

4、寻找两个正序数组的中位数

题目内容

题解

5、最长回文子串

题目内容

题解

 

6、盛水最多的容器

题目内容

题解

7、三数之和

题目内容

题解

8、电话号码的字母组合

题目内容

题解

9、删除链表中倒数第n个节点

题目内容

题解


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]

题解

这道题比较简单,我是直接对原数组进行深拷贝后,排序成递增数组,然后使用双指针寻找相加等于target的两个值,然后在原数组中找出索引即可。双指针的优势就是,可以同时在两个方向上往中间遍历,且可以根据数字大小决定移动方向。

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  let arr = JSON.parse(JSON.stringify(nums));
  arr.sort((a, b) => (a < b ? -1 : 1));
  // 双指针
  let l = 0,
    r = arr.length - 1;
  while (l < r) {
    if (arr[l] + arr[r] === target) {
      break;
    } else if (arr[l] + arr[r] < target) {
      l++;
    } else {
      r--;
    }
  }
  let temp = 0;
  let pos1 = nums.indexOf(arr[l]);
  let pos2 =
    (temp = nums.indexOf(arr[r])) === pos1 ? nums.lastIndexOf(arr[r]) : temp;
  return [pos1, pos2];
};

官方题解的思路是将nums中的数字及其位置存入哈希表,然后这样就可以遍历一次得到结果了。按照这个思路,我实现了一次。

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  const map = {};
  for (let i = 0; i < nums.length; i++) {
    let num = nums[i];
    if (map[target - num] !== undefined) {
      return [map[target - num], i];
    } else {
      map[num] = i;
    }
  }
};

注意,JS中对象的值可能是undefined,也可能是0,都会判断为false,因此不能简单地使用if(map[target-num]),这样如果map[target-num]是0就进不去了。

在这里不得不哭泣一下,之前刷题都是用Java,对hashmap很熟悉,现在很久没有用Java,居然对hashmap陌生了......

2、两数相等

题目内容

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.


示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]


示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

题解

这道题,我的思路很简单,就是依次遍历每个节点,记录当前相加结果和上一次相加的进位,然后给新链表赋值。需要注意的是,遍历结束后,可能会存在一个空的节点,这时候要判断,如果上一次进位值还有,就把进位值赋给这个节点,否则置空。

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function (l1, l2) {
  // 当前相加值和进位值
  let now = 0,
    last = 0;
  // 结果链表
  let pos = new ListNode(-1),
    res = pos,
    last_pos = null;
  while (l1 || l2) {
    if (!last_pos) {
      last_pos = pos;
    }
    if (l1 && l2) {
      let all = l1.val + l2.val + last;
      now = all % 10;
      last = parseInt(all / 10);
      last_pos = pos;
      pos.val = now;
      pos.next = new ListNode(-1);
      pos = pos.next;
      l1 = l1.next;
      l2 = l2.next;
    } else if (l1) {
      let all = l1.val + last;
      now = all % 10;
      last = parseInt(all / 10);
      last_pos = pos;
      pos.val = now;
      pos.next = new ListNode(-1);
      pos = pos.next;
      l1 = l1.next;
    } else {
      let all = l2.val + last;
      now = all % 10;
      last =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值