1. 力扣86:分隔链表
1.1 题目:
给你一个链表的头节点 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
1.2 思路1:
双队列思路,需要多次遍历链表,一个队列存放小于x的值,另一个队列存放大于等于x的值。
时间复杂度和空间复杂度都很高。
1.3 题解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 partition(ListNode head, int x) {
if(head == null || head.next == null){
return head;
}
// 两个队列直接秒了
// queue1用来存放小于x的节点值
Deque<Integer> queue1 = new LinkedList<>();
Deque<Integer> queue2 = new LinkedList<>();
ListNode p = head;
while(p != null){
if(p.val < x){
queue1.offer(p.val);
}else{
queue2.offer(p.val);
}
p = p.next;
}
p = head;
while(p != null){
if(!queue1.isEmpty()){
p.val = queue1.poll();
}else if (!queue2.isEmpty()){
p.val = queue2.poll();
}
p = p.next;
}
return head;
}
}
2. 力扣328:奇偶链表
2.1 题目:
给定单链表的头节点 head
,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。
第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。
请注意,偶数组和奇数组内部的相对顺序应该与输入时保持一致。
你必须在 O(1)
的额外空间复杂度和 O(n)
的时间复杂度下解决这个问题。
示例 1:
输入: head = [1,2,3,4,5] 输出: [1,3,5,2,4]
示例 2:
输入: head = [2,1,3,5,6,4,7] 输出: [2,3,6,7,1,5,4]
提示:
n ==
链表中的节点数0 <= n <= 104
-106 <= Node.val <= 106
2.2 思路:
一步一步理清怎么将奇数节点插入到最新插入的奇数节点的后面。
2.3 题解:
/**
* 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 oddEvenList(ListNode head) {
// 空链表的情况或链表只有一个节点的情况,直接返回
if(head == null || head.next == null){
return head;
}
// cn节点是从左向有右数,最新交换过来的奇数节点
ListNode cn = head;
// 记录这个节点在链表中的位置
int k = 2;
// p指针遍历链表
ListNode p = head.next;
ListNode parent = head;
while(p != null){
// 奇数需要处理
if(k++ % 2 == 1){
// 记录p的next节点,方便处理完这轮交换,下一轮从p的next节点开始
ListNode temp = p.next;
// 将p节点插入到cn节点的后面
parent.next = p.next;
p.next = cn.next;
cn.next = p;
// 更新各节点信息
cn = cn.next;
// 这里parent节点没必要更新,因为p刚处理完,
// p到了它的下一个节点,它的下一个节点要么有,要么是偶数节点
// 那么就会进入到else代码块,会对parent进行更新。
p = temp;
} else {
parent = p;
p = p.next;
}
}
return head;
}
}