题目1. 链表节点位置调整
https://leetcode.com/problems/partition-list/submissions/
题目简介:输入一个链表和一个值x, 所有小于x的值应该放在大于x的值前面,且所有值相对顺序不变。
题解:给链表加一个头结点,链表从头遍历,记录下第一个大于等于x的值的节点node的前置节点pre,从node往后遍历,凡是小于x的就取出来插入到pre后面,然后更新pre。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode partition(ListNode head, int x) {
if(head == null || head.next == null)return head;
ListNode headnode = new ListNode(-1);
headnode.next = head;
ListNode pre = headnode,cur = headnode.next;
//先找到第一个大于 x 的节点的 “前一个节点” pre
while(cur!= null){
if(cur.val >= x){
break;
}
cur = cur.next;
pre = pre.next;
}
if(cur == null)return head;
// 从pre开始的下一个节点遍历,找到小于 x的节点
ListNode node = pre.next.next ,curpre = pre.next;
while(node != null){
while( node != null && node.val < x ){
ListNode temp = node; //缓存起来
curpre.next = node.next; //挖掉该节点
node = curpre.next; //当前节点位置更新
temp.next = pre.next; //将缓存的节点插入之前的节点
pre.next = temp;
pre = pre.next; //记得更新pre,要不然所有插入的节点全在头部
}
if(node != null){
curpre = curpre.next;
node = node.next;
}
}
return headnode.next; //返回的不是head,而是headnode.next ,因为head可能被移动过,不再是真正的头了
}
}
题目2. 链表深度复制(带随机节点的链表)
https://leetcode.com/problems/copy-list-with-random-pointer/submissions/
题目3. 链表 后半部分交叉插入前半部分
https://leetcode.com/problems/reorder-list/
题目简介:将链表后半部分交叉插入前半部分中。
题解:先找到链表中点,把中点以后的节点压入栈中,然后从链表头开始依次从栈中取出节点插入。 (也可将后半部分反转,然后插入前半部分,一样的)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void reorderList(ListNode head) {
Stack<ListNode> stack = new Stack<>();
ListNode findmid = findmid(head);
if(findmid != null && head != findmid){ //中间节点以后的全部压入栈中
ListNode node = findmid.next;
findmid.next = null;
while(node != null){
ListNode next = node.next;
node.next = null;
stack.push(node);
node = next;
}
}
ListNode headtemp =head;
while(!stack.isEmpty()){ //依次从栈中取出插入
ListNode next = headtemp.next;
ListNode node = stack.pop();
node.next = headtemp.next;
headtemp.next = node;
headtemp = next;
}
}
public ListNode findmid(ListNode head){ //找链表中间节点典型操作
if(head == null || head.next == null)return head;
ListNode NewHead = new ListNode(-1);
NewHead.next = head;
ListNode p1 = NewHead,p2 = NewHead;
while(p2 !=null && p2.next != null){
p1 = p1.next;
p2 = p2.next.next;
}
return p1;
}
}