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 dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode prev = dummyNode;
while (prev.next != null && prev.next.next != null) {
ListNode temp = head.next.next; // 缓存 next
prev.next = head.next; // 将 prev 的 next 改为 head 的 next
head.next.next = head; // 将 head.next(prev.next) 的next,指向 head
head.next = temp; // 将head 的 next 接上缓存的temp
prev = head; // 步进1位
head = head.next; // 步进1位
}
return dummyNode.next;
}
}
注意点:
1、使用虚拟节点
2、while (prev.next != null && prev.next.next != null),循环条件的意思是pre后面还有两个节点,就继续循环。
19.删除链表的倒数第N个节点
题目链接:力扣
文章链接:代码随想录
题目:
给你一个链表,删除链表的倒数第 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 dummy = new ListNode(0);
dummy.next = head;
ListNode fast = dummy;
ListNode slow = dummy;
ListNode pre = null;
while(n-- > 0){
fast = fast.next;
}
while(fast!=null){
pre = slow;
slow = slow.next;
fast = fast.next;
}
pre.next = slow.next;
return dummy.next;
}
}
面试题 02.07. 链表相交
题目链接:力扣
文章链接:代码随想录
题目:
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
思路:
简单来说,就是求两个链表交点节点的指针。
代码:
/**
* 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) {
if(headA == null || headB == null){
return null;
}
ListNode temp1 = headA;
ListNode temp2 = headB;
int lenA = 0;
int lenB = 0;
while(temp1 != null){
lenA ++;
temp1=temp1.next;
}
while(temp2 != null ){
lenB ++;
temp2 = temp2.next;
}
if(lenB > lenA){
int tmpLen = lenA;
lenA = lenB;
lenB = tmpLen;
ListNode tmpNode = headA;
headA = headB;
headB = tmpNode;
}
int gap = lenA - lenB;
while(gap > 0){
headA = headA.next;
gap --;
}
while(headA != null){
if(headA == headB){
return headA;
}
headA = headA.next;
headB = headB.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 temp1 = head;
ListNode temp2 = fast;
while(temp1 != temp2){
temp1 = temp1.next;
temp2 = temp2.next;
}
return temp1;
}
}
return null;
}
}
使用哈希表代码:
/**
* 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 cur = head;
Set<ListNode> set = new HashSet<> ();
while(cur!=null){
if(set.contains(cur)){
return cur;
}else{
set.add(cur);
}
cur = cur.next;
}
return null;
}
}