24. 两两交换链表中的节点
原题链接: 24. 两两交换链表中的节点
解题思路:使用三个指针+虚拟头节点完成交换,注意循环的终止条件以及每个指针每次的移动位数
/**
* 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 swapPairs(ListNode head) {
ListNode nhead = new ListNode(0);
ListNode ptr1, ptr2;
nhead.next = head;
if (head == null)
return head;
if (head.next == null)
return head;
ptr1 = head;
ptr2 = head.next;
ListNode lastnode = nhead;
while (ptr2 != null) {
ptr1.next = ptr2.next;
ptr2.next = ptr1;
lastnode.next = ptr2;
lastnode = lastnode.next;
ptr2 = ptr1.next;
ptr1 = lastnode.next;
if (ptr2 == null)
break;
ptr2 = ptr2.next;
ptr1 = ptr1.next;
lastnode = lastnode.next;
}
return nhead.next;
}
}
19.删除链表的倒数第N个节点
原题链接: 19.删除链表的倒数第N个节点
解题思路:双指针(不是快慢指针)
/**
* 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 removeNthFromEnd(ListNode head, int n) {
ListNode ptr1, ptr2;
ListNode nhead = new ListNode(0);
nhead.next = head;
ptr1 = nhead;
ptr2 = nhead;
for (int i = 0; i < n; i++) {
ptr2 = ptr2.next;
}
while (ptr2.next != null) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
ptr1.next = ptr1.next.next;
return nhead.next;
}
}
面试题 02.07. 链表相交
原题链接: 面试题 02.07. 链表相交
解题思路:双指针
/**
* 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) {
int lenA=0;
int lenB=0;
ListNode ptr1 = headA;
ListNode ptr2 = headB;
int dif=0;
if(headA==null||headB==null)
return null;
while(ptr1.next != null){
ptr1 = ptr1.next;
lenA++;
}
while(ptr2.next != null){
ptr2 = ptr2.next;
lenB++;
}
if(lenA>lenB){
dif = lenA - lenB;
ptr1 = headA;
ptr2 = headB;
for(int i=0;i<dif;i++){
ptr1=ptr1.next;
}
while(ptr1.next!=null){
if(ptr1==ptr2){
return ptr1;
}
ptr1=ptr1.next;
ptr2=ptr2.next;
}
}else{
dif = lenB - lenA;
ptr1 = headA;
ptr2 = headB;
for(int i=0;i<dif;i++){
ptr2=ptr2.next;
}
while(ptr2.next!=null){
if(ptr1==ptr2){
return ptr2;
}
ptr1=ptr1.next;
ptr2=ptr2.next;
}
}
if(ptr1==ptr2)
return ptr1;
return null;
}
}
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 ptr1, ptr2;
if (head == null)
return null;
if (head.next == null)
return null;
ptr1 = head;
ptr2 = head;
while (ptr2.next != null) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
if (ptr2.next == null)
return null;
ptr2 = ptr2.next;
if (ptr1 == ptr2)
break;
}
if (ptr2.next == null)
return null;
ptr1 = head;
while (ptr1 != ptr2) {
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
return ptr1;
}
}