学习目标:
- 完成链表相关题目
学习内容:
24. 两两交换链表中的节点
题目:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
涉及到链表交换顺序的题目一般都需要设置虚拟头节点,因为这样就可以将头节点与后面的节点一起处理,并不用分类讨论。
解决这题时需要先画图,将修改顺序的示意图画出来,再按照此过程将一次修改的代码写出来,最后再加入循环操作。
另外,需要注意循环条件中cur.next != null需要写在前面,否则如果cur.next为空再取cur.next.next会造成空指针异常。
/**
* 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 dummy= new ListNode(0, head);
ListNode cur = dummy;
while(cur.next != null && cur.next.next != null){
ListNode temp = cur.next;
ListNode temp1 = cur.next.next.next;
cur.next = cur.next.next;
cur.next.next = temp;
temp.next = temp1;
cur = cur.next.next;
}
return dummy.next;
}
}
19.删除链表的倒数第N个节点
题目:给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
这题同样需要一个虚拟节点,因为链表中删除任何元素都需要被删除元素的前一个结点。
另外,这题也使用到了双指针,也就是快慢指针。当快指针为空时,慢指针就会指向被删除节点的前一个结点。代码中先让n+1也是为了让慢指针在结束循环时正好指在被删除元素的前一个位置。
/**
* 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 dummy = new ListNode(0, head);
ListNode slow = dummy;
ListNode fast = dummy;
n++;
while(n!=0 && fast!=null){
fast = fast.next;
n--;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
}
面试题 02.07. 链表相交
题目:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
先让长度长的链先往前走几个节点,走到两条链长度相同后,两条链的指针再一起往前走,这样子当两个指针指向同个节点时就代表找到了相交节点。 因此,需要先算出两条链差多少节点。
/**
* 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) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0;
int lenB = 0;
while(curA != null){
curA = curA.next;
lenA++;
}
while(curB != null){
curB = curB.next;
lenB++;
}
curA = headA;
curB = headB;
if(lenB > lenA){
//交换长度
int temp = lenA;
lenA = lenB;
lenB = temp;
//交换头指针
ListNode temp1 = curA;
curA = curB;
curB = temp1;
}
int n = lenA - lenB;
while(n > 0){
n--;
curA = curA.next;
}
while(curB != null){
if(curA == curB){
return curA;
}
curA = curA.next;
curB = curB.next;
}
return null;
}
}
142.环形链表II
题目:
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
/**
* 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 fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
ListNode index1 = head;
ListNode index2 = fast;
while(index1 != index2){
index1 = index1.next;
index2 = index2.next;
}
return index1;
}
}
return null;
}
}
今日收获:
解决链表相关题目的思想。