24.两两交换链表中的节点
自己的:
不够简洁。
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode fakehead = new ListNode(0);
fakehead.next = head;
ListNode pre = fakehead;
ListNode first = head;
ListNode second = head.next;
head = head.next;
while (first.next != null) {
first.next = second.next;
second.next = first;
pre.next = second;
if (first.next != null) {
pre = first;
first = first.next;
second = first.next;
}
}
return head;
}
}
迭代官方:
所有都在哑节点的基础上操作,循环终止条件是判断哑节点是否有下家和下下家
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode temp = dummyHead;
while (temp.next != null && temp.next.next != null) {
ListNode node1 = temp.next;
ListNode node2 = temp.next.next;
temp.next = node2;
node1.next = node2.next;
node2.next = node1;
temp = node1;
}
return dummyHead.next;
}
}
递归:
首先head就是当前,newHead是第二个,因为逆转后第二个会变成第一个所以是新头。
这道就是每次传入head,然后定义newHead,然后将newHead.next传入下一次递归当作下一次的head。【head1,newHead1,head2,newHead2,head3,newHead3....headn-1,newHeadn-1,headn】
返回值的选择要看每次递归之间的联系,这里就是上一次的newHead是这一次的下一个节点,所以要返回newHead。
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode newHead = head.next;
head.next = swapPairs(newHead.next);
newHead.next = head;
return newHead;
}
}
19.删除链表的倒数第n个节点
设立两个相距n的指针,第一个指针设立在虚拟节点上,第二个设立在head,走了n步后第一个就是目标节点的前一个节点。
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
if(head==null)
return head;
ListNode fakehead=new ListNode(0);
fakehead.next=head;
ListNode cur=fakehead;
ListNode qury = head;
int i = 0;
while (qury != null && i < n) {
qury = qury.next;
i++;
}
while(qury!=null){
cur=cur.next;
qury=qury.next;
}
cur.next=cur.next.next;
return fakehead.next;
}
}
160.相交链表
自己(随想录版):
首先获取两个链表的长度,然后让长的链表先走差值的距离,最后两个一起走。
判断两个链表交点的条件是两个指针指向同一节点,而不是指向节点的值相等。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode a = headA;
ListNode b = headB;
int aLength = 0;
int bLength = 0;
while (a != null || b != null) {
if (a != null) {
a = a.next;
aLength++;
}
if (b != null) {
b = b.next;
bLength++;
}
}
int dif=Math.abs(aLength-bLength);
if(aLength>bLength){
for(int i=0;i<dif;i++){
headA=headA.next;
}
}else{
for(int i=0;i<dif;i++){
headB=headB.next;
}
}
while(headA!=headB){
headA=headA.next;
headB=headB.next;
}
return headA;
}
}
leetcode简洁版:
无敌了这个a+b+c的判断方法。
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;
}
}
142.环形链表
数学推理哈哈,这个版本比leetcode的简洁。
public class Solution {
public ListNode detectCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
ListNode meet = head;
while (meet != slow) {
meet = meet.next;
slow = slow.next;
}
return meet;
}
}
return null;
}
}