对于单链表相关的问题,双指针技巧是一种非常广泛且有效的解决方法。以下是一些常见问题以及使用双指针技巧解决🚀🚀:
总的来说,双指针技巧在解决单链表相关问题时非常实用,它能够高效地解决许多常见问题,包括合并、分解、寻找节点、判断是否存在环等等。
给你单链表的头结点
head
,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:head = [1,2,3,4,5]
输出:[3,4,5]
解释:链表只有一个中间结点,值为 3 。
示例 2:
输入:head = [1,2,3,4,5,6]
输出:[4,5,6]
解释:该链表有两个中间结点,值分别为 3 和 4 ,返回第二个结点。
提示:
[1, 100]
1 <= Node.val <= 100
判断快指针是否可以移动 快指针移动两部,慢指针移动一步,当快指针无法移动时,快指针的位置是链表的倒数第一或倒数第二节点,只需要进行判断,如果是倒数第一,直接返回慢指针,如果是倒数第二,返回慢指针的下一个节点。
/**
* 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 middleNode(ListNode head) {
//定义快慢指针
ListNode first=head,slow=head;
//判断快指针是否可以移动 快指针移动两部,慢指针移动一步,当快指针无法移动时,快指针的位置是链表的倒数第一或倒数第二节点,只需要进行判断,如果是倒数第一,直接返回慢指针,如果是倒数第二,返回慢指针的下一个节点。
while(first.next!=null && first.next.next!=null){
first=first.next.next;
slow=slow.next;
}
if(first.next!=null){
return slow.next;
}
return slow;
}
}
给你一个链表的头节点
head
和一个特定值x
,请你对链表进行分隔,使得所有 小于x
的节点都出现在 大于或等于x
的节点之前。你应当 保留 两个分区中每个节点的初始相对位置。
示例 1:
输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]
示例 2:
输入:head = [2,1], x = 2
输出:[1,2]
提示:
[0, 200]
内-100 <= Node.val <= 100
-200 <= x <= 200
/**
* 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 partition(ListNode head, int x) {
ListNode dump=new ListNode(-1);
ListNode temp=new ListNode(-1);
ListNode result=dump;
ListNode result1=temp;
//使用双指针将小于x放在第一个指针,大于等于x放在第二个指针,再将两者相接即可
while(head!=null){
if(head.val>=x){
temp.next=new ListNode(head.val);
temp=temp.next;
}else{
dump.next=new ListNode(head.val);
dump=dump.next;
}
head=head.next;
}
dump.next=result1.next;
return result.next;
}
}