6.25 二刷hot100 链表
This commit is contained in:
parent
c1899dd270
commit
9e0b5945a2
@ -8,6 +8,7 @@ package linkedlist;
|
||||
* 链接:https://leetcode.cn/problems/add-two-numbers/
|
||||
|
||||
*/
|
||||
// 二刷会做
|
||||
public class AddTwoNumbers {
|
||||
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
|
||||
ListNode dummy = new ListNode(-1);
|
||||
|
@ -7,10 +7,12 @@ import java.util.HashSet;
|
||||
* 描述:给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
|
||||
* 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
|
||||
* 不允许修改 链表。
|
||||
进阶:你是否可以使用 O(1) 空间解决此题?
|
||||
|
||||
* 链接:https://leetcode.cn/problems/linked-list-cycle-ii/
|
||||
|
||||
*/
|
||||
//二刷不会做 推导忘记
|
||||
public class DetectCycle {
|
||||
//哈希
|
||||
public ListNode detectCycle1(ListNode head) {
|
||||
@ -26,28 +28,24 @@ public class DetectCycle {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
//Floyd 快慢指针
|
||||
//Floyd 快慢指针 如果链表中存在环,则 fast 指针最终将再次与 slow 指针在环中相遇。
|
||||
public ListNode detectCycle(ListNode head) {
|
||||
if (head == null) {
|
||||
return null;
|
||||
}
|
||||
if (head == null) return null;
|
||||
ListNode slow = head, fast = head;
|
||||
while (fast != null) {
|
||||
slow = slow.next;
|
||||
if (fast.next != null) {
|
||||
fast = fast.next.next;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
if (fast == slow) {
|
||||
// 当 fast 或 fast.next 为 null 时跳出,说明无环
|
||||
while (fast != null && fast.next != null) {
|
||||
slow = slow.next; // 慢指针走一步
|
||||
fast = fast.next.next; // 快指针走两步
|
||||
if (slow == fast) { // 相遇——确认有环
|
||||
// 第二阶段:找到环的入口
|
||||
ListNode ptr = head;
|
||||
while (ptr != slow) {
|
||||
ptr = ptr.next;
|
||||
ptr = ptr.next;
|
||||
slow = slow.next;
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return null; // fast 走到末尾, 无环
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,14 @@ import java.util.HashSet;
|
||||
* 描述:给你一个链表的头节点 head ,判断链表中是否有环。
|
||||
* 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
|
||||
* 如果链表中存在环 ,则返回 true 。 否则,返回 false 。
|
||||
进阶:你能用 O(1)(即,常量)内存解决此问题吗?
|
||||
|
||||
* 链接:https://leetcode.cn/problems/linked-list-cycle/
|
||||
输入:head = [3,2,0,-4], pos = 1
|
||||
输出:true
|
||||
解释:链表中有一个环,其尾部连接到第二个节点。
|
||||
*/
|
||||
//二刷会做
|
||||
public class HasCycle {
|
||||
//哈希法
|
||||
public boolean hasCycle1(ListNode head) {
|
||||
@ -58,19 +60,26 @@ public class HasCycle {
|
||||
// 走到空指针,说明无环
|
||||
return false;
|
||||
}
|
||||
//快慢指针法
|
||||
public boolean hasCycle(ListNode head) {
|
||||
if (head == null || head.next == null) {
|
||||
return false;
|
||||
}
|
||||
if (head == null) return false;
|
||||
|
||||
// 快慢指针都从 head 出发
|
||||
ListNode slow = head;
|
||||
ListNode fast = head.next;
|
||||
while (slow != fast) {
|
||||
if (fast == null || fast.next == null) {
|
||||
return false;
|
||||
ListNode fast = head;
|
||||
|
||||
// 当 fast 或 fast.next 为 null 时,说明已经到链表末尾,无环
|
||||
while (fast != null && fast.next != null) {
|
||||
slow = slow.next; // 慢指针走一步
|
||||
fast = fast.next.next; // 快指针走两步
|
||||
|
||||
// 每走一步就检查一次相遇
|
||||
if (slow == fast) {
|
||||
return true; // 相遇则有环
|
||||
}
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
return true;
|
||||
|
||||
return false; // 跳出循环说明没有环
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,12 +6,13 @@ import java.util.List;
|
||||
/**
|
||||
* 题目:234. 回文链表 (isPalindrome)
|
||||
* 描述:给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
|
||||
|
||||
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
|
||||
* 链接:https://leetcode.cn/problems/palindrome-linked-list/
|
||||
|
||||
*/
|
||||
//二刷会做
|
||||
public class IsPalindrome {
|
||||
public boolean isPalindrome(ListNode head) {
|
||||
public boolean isPalindrome1(ListNode head) {
|
||||
ListNode temp=head;
|
||||
List<Integer>list=new ArrayList<>();
|
||||
while (head!=null){
|
||||
@ -26,7 +27,7 @@ public class IsPalindrome {
|
||||
return true;
|
||||
}
|
||||
//快慢指针 + 链表反转
|
||||
public boolean isPalindrome1(ListNode head) {
|
||||
public boolean isPalindrome(ListNode head) {
|
||||
if (head == null || head.next == null) {
|
||||
return true; // 空链表或只有一个节点,直接返回 true
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.util.List;
|
||||
* 链接:https://leetcode.cn/problems/merge-two-sorted-lists/
|
||||
|
||||
*/
|
||||
//二刷会做
|
||||
public class MergeTwoLists {
|
||||
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
|
||||
ListNode head = new ListNode(-1);
|
||||
|
@ -7,12 +7,16 @@ import java.util.LinkedList;
|
||||
/**
|
||||
* 题目: 19. 删除链表的倒数第 N 个结点 (removeNthFromEnd)
|
||||
* 描述:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
|
||||
|
||||
|
||||
进阶:你能尝试使用一趟扫描实现吗?
|
||||
* 链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
|
||||
|
||||
*/
|
||||
//二刷会做
|
||||
public class RemoveNthFromEnd {
|
||||
//思路:
|
||||
//1. 遍历一遍链表,用哈希表存储每个节点的位置
|
||||
//2. 找到倒数第n个节点的前一个节点,修改指针
|
||||
//3. 注意边界情况,如删除头节点
|
||||
public ListNode removeNthFromEnd1(ListNode head, int n) {
|
||||
HashMap<Integer,ListNode>map=new HashMap<>();
|
||||
int k=0;
|
||||
@ -28,7 +32,11 @@ public class RemoveNthFromEnd {
|
||||
return head;
|
||||
}
|
||||
//入栈 出栈
|
||||
public ListNode removeNthFromEnd(ListNode head, int n) {
|
||||
//思路:
|
||||
//1. 遍历一遍链表,用栈存储每个节点
|
||||
//2. 找到倒数第n个节点的前一个节点,修改指针
|
||||
//3. 注意边界情况,如删除头节点
|
||||
public ListNode removeNthFromEnd2(ListNode head, int n) {
|
||||
ListNode dummy = new ListNode(0,head);
|
||||
Deque<ListNode> stack = new LinkedList<>();
|
||||
ListNode cur = dummy;
|
||||
@ -44,4 +52,38 @@ public class RemoveNthFromEnd {
|
||||
ListNode ans = dummy.next;
|
||||
return ans;
|
||||
}
|
||||
|
||||
//思路:
|
||||
//1. 定义两个指针,first和second,都指向 dummy
|
||||
//2. 让 first 向前走 n+1 步
|
||||
//3. 同时移动,两指针保持 n+1 步差距
|
||||
//4. 此时 second.next 是要删除的节点,直接跳过它
|
||||
//5. 返回删除后的链表头
|
||||
public ListNode removeNthFromEnd(ListNode head, int n) {
|
||||
// 1. 创建虚拟头节点
|
||||
ListNode dummy = new ListNode(0);
|
||||
dummy.next = head;
|
||||
|
||||
// 2. 初始化快慢指针,都指向 dummy
|
||||
ListNode first = dummy;
|
||||
ListNode second = dummy;
|
||||
|
||||
// 3. 先让 first 向前走 n+1 步
|
||||
for (int i = 0; i < n + 1; i++) {
|
||||
first = first.next;
|
||||
}
|
||||
|
||||
// 4. 同时移动,两指针保持 n+1 步差距
|
||||
while (first != null) {
|
||||
first = first.next;
|
||||
second = second.next;
|
||||
}
|
||||
|
||||
// 5. 此时 second.next 是要删除的节点,直接跳过它
|
||||
second.next = second.next.next;
|
||||
|
||||
// 6. 返回删除后的链表头
|
||||
return dummy.next;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user