总结一些力扣算法题的较优解法,若有更好的主意欢迎评论
更多练习:https://leetcode.cn/problemset/all/
1.给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值target
的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例:
输入:nums = [3,2,4], target = 6
输出:[1,2]
import java.util.HashMap;
import java.util.Map;
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> hash = new HashMap<>();
for (int i = 0, j = nums.length - 1; i < nums.length; i++, j--) {
if (hash.containsKey(nums[i])) return new int[]{hash.get(nums[i]), i};
hash.put(target - nums[i], i);
if (hash.containsKey(nums[j])) return new int[]{hash.get(nums[j]), j};
hash.put(target - nums[j], j);
}
return null;
}
}
解题思路:
nums=[ 3 , 2 , 4 ] target=6 i=0 j=2
hash初始化:
key value
nums=[ 3 , 2 , 4 ] target=6 i=0
hash中没有为3的值,所以将 target-num[ i ] 和 i 存入hash中
hash变化:
key 3 value 0
nums=[ 3 , 2 , 4 ] target=6 j=2
hash中没有为4的值,所以将 target-num[ j ] 和 j 存入hash中
hash变化:
key 3 2 value 0 2
nums=[ 3 , 2 , 4 ] target=6 i=1
hash中找到了key为2的数据,并且 value为2,则返回(2,1)
2.给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,
并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807
示例2:
输入:l1 = [0], l2 = [0]
输出:[0]
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode newListNode= new ListNode(-1),
pre = newListNode;
int t = 0;
while (l1 != null || l2 != null || t != 0) {
if (l1 != null) {
t += l1.val;
l1 = l1.next;
}
if (l2 != null) {
t += l2.val;
l2 = l2.next;
}
pre.next = new ListNode(t % 10);
pre = pre.next;
t /= 10;
}
return newListNode.next;
}
}
解题思路:
首先,要创建一个新的链表用来存储计算后的节点;
第二,创建一个变量t用来存储 l1 和 l2 对应节点计算后的和,以及进位值;
第三,用 t / 10 计算值来决定是否有进位,结果为1则是有进位值,为0则没有进位;
第四,t%10 则为每个位相加后的计算结果,存到新的链表中。
以 l1 = [2,4,3], l2 = [5,6,4] 为例:
l1 指向存储2的节点 → l2 指向存储5的节点
t=7 → l1指向 l1.next(存储4的节点) → l2指向 l2.next(存储6的节点 )
pre.next 存入 t%10 的结果为 7 → pre指向pre.next → t/10=0 没有进位
t=10 → l1指向 l1.next(存储3的节点) → l2指向 l2.next(存储4的节点 )
pre.next 存入 t%10 的结果为 0 → pre指向pre.next → t/10=1 有进位
t=8 → l1指向 l1.next(null) → l2指向 l2.next(null )
pre.next 存入 t%10 的结果为 8 → pre指向pre.next → t/10=0 没有进位
此时 l1=null l2= null t=0 满足循环结束条件
3.给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例4:
输入: s = " "
输出: 1
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>();
for (int end = 0, start = 0; end < n; end++) {
char alpha = s.charAt(end);
if (map.containsKey(alpha)) {
start = Math.max(map.get(alpha), start);
}
ans = Math.max(ans, end - start + 1);
map.put(s.charAt(end), end + 1);
}
return ans;
}
}
解题思路:
滑动窗口法
首先需要定义几个变量,他们分别代表起点位置终点位置和起点与终点的距离。
滑动过程:
循环开始,start 和 end 都指字符 'P' 的位置,此时P所在的方格就是一个窗口;
P
start end
W W K E W 执行开始: alpha=p,
到map中查询有没有key为 ‘P’ 的数据,发现没有,不执行if语句,
ans=Math.max(ans, end - start + 1)=Math.max(0, 0 - 0 + 1)= 1
map:
key P value
1
end++,start 位置不变,仍然指向字符 'P' 的位置,end指向 'W' ,此时 'PW' 所在的方格就是一个窗口;
P
start
W
end
W
K E W alpha=W,
到map中查询有没有key为 ‘W’ 的数据,发现没有,不执行if语句,
ans= Math.max(ans, end - start + 1)=Math.max(1, 1 - 0 + 1)= 2
map:
key P W value
1 2
end++,start 指向字符 'W' 的位置,end指向 'W' ,此时 'W' 所在的方格就是一个窗口;
P W W
start end
K E W
alpha=W;
到map中查询,此时存在key为 ‘W’ 的数据,执行if语句,此时start=2;
ans= Math.max(ans, end - start + 1)=Math.max(2, 2 - 2 + 1)=2;
map:
key P W value
1 3
end++,start 指向字符 'W' 的位置,end指向 'K' ,此时 'WK' 所在的方格就是一个窗口;
P W W
start
K
end
E W alpha=K;
到map中查询有没有key为 ‘k’ 的数据,发现没有,不执行if语句;
ans= Math.max(ans, end - start + 1)=Math.max(2, 3 - 2 + 1)=2;
map:
key P W K value
1 3 4
end++,start 指向字符 'W' 的位置,end指向 'E' ,此时 'WKE' 所在的方格就是一个窗口;
P W W
start
K E
end
W alpha=E;
到map中查询有没有key为 ‘E’ 的数据,发现没有,不执行if语句;
ans= Math.max(ans, end - start + 1)=Math.max(2, 4 - 2 + 1)=3;
map:
key P W K E value
1 3 4 5
end++,start 指向字符 'K' 的位置,end指向 最后一个'W' ,此时 'KEW' 所在的方格就是一个窗口;
alpha=W;
P W W K
start
E W
end
到map中查询,此时存在key为 ‘W’ 的数据,执行if语句,此时start=3;
ans= Math.max(ans, end - start + 1)=Math.max(3, 5 - 3 + 1)=3;
map:
key P W K E value
1 6 4 5
循环结束,返回ans