链表题继续刷起来。
目录
1. 相交链表
此题的一种思路是:
分别算出两个链表长度,然后让短的先走他们长度的插值
这样两个链表在同一起点,一起往后走
直到遇到相同节点就返回(如果没有相同的他们一起到null了)
代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null && headB == null){
return null;
}
ListNode p1 = headA;
ListNode p2 = headB;
int lenA = 0;
int lenB = 0;
while (p1 != null){
lenA++;
p1 = p1.next;
}
while (p2 != null){
lenB++;
p2 = p2.next;
}
p1 = headA;
p2 = headB;
int len = lenA - lenB;
if (len < 0){
p1 = headB;
p2 = headA;
len = lenB - lenA;
}
while (len != 0){
p1 = p1.next;
len--;
}
while (p1 != p2){
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
}
当然,这种解法有点长。
官方给的解法很精炼:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode pA = headA, pB = headB;
while (pA != pB) {
pA = pA == null ? headB : pA.next;
pB = pB == null ? headA : pB.next;
}
return pA;
}
}
他们各走各的,到了空就到另一个链表上走
最终要么一起相等,要么都是null,并返回。
看到两个评论我直接悟了:
2.反转链表
逆序链表,可以让下一个节点的next设置为本节点。
但本节点没有引用其前一个节点,因此必须事先存储其前一个节点。
并且在更改引用之前,还需要存储后一个节点。
最后返回新的头引用。
代码:
class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) return null;
ListNode prev = head;
ListNode cur = head.next;
while (cur != null){
ListNode curNext = cur.next;
cur.next = prev;
prev = cur;
cur = curNext;
}
head.next = null;
return prev;
}
}
3.链表的中间节点
这题我们可以用快慢指针
快指针走两步,慢指针走一步
最终快指针到头时,慢指针正好走一半
class Solution {
public ListNode middleNode(ListNode head){
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
4. 回文链表
运用快慢指针,当slow走到中间值,反转后面的链表
(正好运用第二题和第三题)
反转后比较即可。
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast = head;
ListNode slow = head;
//让slow走到中间
while (fast != null && fast.next != null){//要先判断fast
fast = fast.next.next;
slow = slow.next;
}
//开始反转
ListNode cur = slow.next;
while (cur != null){
ListNode curNext = cur.next;
cur.next = slow;
slow = cur;
cur = curNext;
}
//比较
while (head != slow){
//只要有值不相同,false
if (head.val != slow.val){
return false;
}
//如果相遇,true(比如[1,2,1])
if (head.next == slow){
return true;
}
head = head.next;
slow = slow.next;
}
//最终都为能出来,就是回文
return true;
}
}
🦀🦀👍