【LeetCode hot100|Week4】链表
笔记用于个人复习和巩固,题解非原创,参考LeetCode官方题解以及各个大佬的解法,希望给大家带来帮助,同时笔记也能督促我学习进步
这周主要把链表一部分的题目刷了一遍
链表周刷题总结 本周集中练习了链表相关题目,主要涉及以下知识点: 相交链表:使用哈希表存储访问过的节点,通过双指针遍历查找交点(160题) 反转链表:迭代法修改指针指向,逐步反转链表(206题) 回文链表:将链表值存入数组后用双指针判断回文(234题) 环形链表检测:哈希表记录访问节点,判断是否出现环(141/142题) 合并有序链表:创建虚拟头节点,通过比较节点值逐步构建新链表(21题) 解题技巧: 哈希表用于记录访问历史 双指针法处理遍历和比较 虚拟头节点简化链表操作 注意指针移动顺序和边界条件 笔记记
文章目录
- Week4
- D1
- 160. 相交链表
- D2
- 206. 反转链表
- D3
- 234. 回文链表
- D4
- 141. 环形链表
- D5
- 142. 环形链表 II
- D6
- 21. 合并两个有序链表
- D7
- 2. 两数相加
Week4
D1
160. 相交链表
160. 相交链表
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {Set<ListNode>visited = new HashSet<ListNode>();ListNode temp = headA;while (temp != null) {visited.add(temp);temp = temp.next;}temp = headB;while (temp != null) {if (visited.contains(temp)) {return temp;}temp = temp.next;}return null;}
}
遍历一个链表存入Set里,再遍历另一个查找有没有一样的
D2
206. 反转链表
206. 反转链表
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr != null) {ListNode next = curr.next;curr.next = prev;prev = curr;curr = next;}return prev;}
}
D3
234. 回文链表
234. 回文链表
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/class Solution {public boolean isPalindrome(ListNode head) {List<Integer> vals = new ArrayList<Integer>();// 将链表的值复制到数组中ListNode currentNode = head;while (currentNode != null) {vals.add(currentNode.val);currentNode = currentNode.next;}// 使用双指针判断是否回文int front = 0;int back = vals.size() - 1;while (front < back) {if (!vals.get(front).equals(vals.get(back))) {return false;}front++;back--;}return true;}
}
List
不能使用 []
来获取或设置元素
==
vsequals()
比较方式 | 含义 |
---|---|
== | 比较两个引用是否指向同一个对象(即内存地址是否相同) |
.equals() | 比较两个对象的内容是否相等(可被重写) |
D4
141. 环形链表
141. 环形链表
public class Solution {public boolean hasCycle(ListNode head) {Set<ListNode> seen = new HashSet<ListNode>();while (head != null) {if (!seen.add(head)) {return true;}head = head.next;}return false;}
}
seen.add(head)
:尝试把当前节点head
添加到集合中。- 如果该节点之前没访问过,添加成功,返回
true
。 - 如果该节点已经存在(说明之前访问过),添加失败,返回
false
。
- 如果该节点之前没访问过,添加成功,返回
D5
142. 环形链表 II
142. 环形链表 II
/*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val = x;* next = null;* }* }*/
public class Solution {public ListNode detectCycle(ListNode head) {ListNode pos = head;Set<ListNode> visited = new HashSet<ListNode>();while (pos != null) {if (visited.contains(pos)) {return pos;} else {visited.add(pos);}pos = pos.next;}return null;}
}
D6
21. 合并两个有序链表
21. 合并两个有序链表
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode dummy = new ListNode();ListNode cur = dummy; // cur 指向新链表的末尾while (list1 != null && list2 != null) {if (list1.val < list2.val) {cur.next = list1; // 把 list1 加到新链表中list1 = list1.next;} else { // 注:相等的情况加哪个节点都是可以的cur.next = list2; // 把 list2 加到新链表中list2 = list2.next;}cur = cur.next;}cur.next = list1 != null ? list1 : list2; // 拼接剩余链表return dummy.next;}
}
D7
2. 两数相加
2. 两数相加
/*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val = val; }* ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode head = null,tail = null;int carry = 0;while(l1 != null || l2 != null){int n1 = l1 != null ? l1.val : 0;int n2 = l2 != null ? l2.val : 0;int sum = n1 + n2 + carry;if(head == null){head = tail = new ListNode(sum % 10);}else{tail.next = new ListNode(sum % 10);tail = tail.next;}carry = sum / 10;if(l1 != null){l1 = l1.next;}if(l2 != null){l2 = l2.next;}}//如到最后还有进位就再增加一个节点if(carry > 0){tail.next = new ListNode(carry);}return head;}
}