目录
剑指21.删除链表的倒数第n个节点
思路解析:
源代码👇
https://leetcode-cn.com/problems/SLwz0R/submissions/
package leetcode;
public class offer_21 {
//删除链表的倒数第n个节点
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(0);
ListNode cur = dummyHead;
dummyHead.next = head;
ListNode prev = null;
int i =1;
while (head!=null){
if (i>=n){
prev = cur;
cur = cur.next;
}
head = head.next;
i++;
}
prev.next = prev.next.next;
return dummyHead.next;
}
}
剑指22.链表的倒数第k个节点
思路解析:
源代码👇
package leetcode;
public class offer_22 {
//链表中倒数第K个节点
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head,low = head;
for (int i = 0; i < k; i++) {
fast = fast.next; //fast先走k个节点
}
while (fast!=null){
fast = fast.next;
low = low.next;
}
return low; //fast为空,此时low节点即为所求
}
}
234.回文链表
思路解析:
源代码👇
https://leetcode-cn.com/problems/palindrome-linked-list/submissions/
package leetcode;
// 回文链表 = 中间节点 + 反转链表
public class Num234 {
public boolean isPalindrome(ListNode head) {
// 1.找到中间节点
ListNode middleNode = middleNode(head);
// 2.反转中间节点后的子链表
ListNode l2 = reverseList(middleNode);
// 同时遍历原先链表l1
while (l2!=null){
if (head.val!=l2.val){
return false;
}
l2 = l2.next;
head = head.next;
}
return true;
}
public ListNode middleNode(ListNode head) {
//fast一次走两步,low一次走一步
ListNode fast = head;
ListNode low = head;
while (fast!=null&&fast.next!=null){
fast=fast.next.next;
low=low.next;
}
return low;
}
public ListNode reverseList(ListNode head) {
if (head==null||head.next==null){
return head;
}
ListNode sec = head.next;
// 反转第二个节点之后的子链表
ListNode newHead = reverseList(head.next);
sec.next = head;
head.next = null;
return newHead;
}
}
141.环形链表
思路:采用快慢指针法,如果快指针指向不为空,并且快指针的下一个节点不为空,快指针一次移动两个单位,慢指针一次移动一个单位,若链表有环,快慢指针必会相遇。
源代码👇
https://leetcode-cn.com/problems/palindrome-linked-list/submissions/
package leetcode;
//环形链表
public class Num141 {
public boolean hasCycle(ListNode head) {
ListNode fast = head,low = head;
while (fast!=null && fast.next!=null){
fast = fast.next.next;
low = low.next;
if (fast == low){
return true;
}
}
return false;
}
}
142.环形链表Ⅱ
思路解析:
源代码👇
https://leetcode-cn.com/problems/palindrome-linked-list/submissions/
package leetcode;
//环形链表Ⅱ 环的入口
public class Num142 {
public ListNode detectCycle(ListNode head) {
ListNode fast = head,low = head;
while (fast!=null&&fast.next!=null){
fast = fast.next.next;
low = low.next;
//此时low和fast相遇
if (fast==low){
ListNode third = head;
while (third!=low){
third = third.next;
low = low.next;
}
return low;
}
}
return null;
}
}
160.相交链表
思路解析:
源代码👇
https://leetcode-cn.com/problems/palindrome-linked-list/submissions/
package leetcode;
//相交链表
public class Num160 {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pA = headA;
ListNode pB = headB;
// 相交时刚好返回交点, 不相交两个同时走到null
while (pA!=pB){
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
21.合并两个有序链表
思路:采用尾插法,先考虑边界条件,也就是 list1 和 list2 各为空时分别返回 list2 和 list1 ,当两个子链表都不为空,如果 list1 中的值大于 list2 中节点的值,直接在虚拟头节点后拼接 list1 即可。
源代码👇
https://leetcode-cn.com/problems/palindrome-linked-list/submissions/
package leetcode;
//合并两个有序链表
public class Num21 {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummyHead = new ListNode(101);
if (list1==null){
return list2;
}
if (list2==null){
return list1;
}
ListNode last = dummyHead;
// l1和l2都不为空
while (list1!=null && list2!=null){
if (list1.val<= list2.val){
last.next = list1;
last = list1;
list1 = list1.next;
}else{
last.next = list2;
last = list2;
list2 = list2.next;
}
}
// 此时l1或l2为空
if (list1==null){
last.next = list2;
}
if (list2==null){
last.next = list1;
}
return dummyHead.next;
}
}
递归法:
package leetcode;
//合并两个有序链表
public class Num21 {
// 递归法
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
}
if (list2 == null) {
return list1;
}
if (list1.val <= list2.val) {
// 说明此时要把list1.next和整个list2交给merge
// 然后将结果拼接到list1.next
list1.next = mergeTwoLists(list1.next,list2);
return list1;
}else {
list2.next = mergeTwoLists(list1,list2.next);
return list2;
}
}
}
本小节完^_^