Given a linked list and a value
x
, partition it such that all nodes less than
x
come before nodes greater than or equal to
x
.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given
1->4->3->2->5->2 and
x = 3,
return
1->2->2->4->3->5.
如果是数组的话 partition很简单 two pointer就可以了
first从前向后找大于x的值 second从后向前找小于x的值 swap就可以了
但这个是链表 没有办法从后向前遍历 即使reverse一下 空间复杂度就变为O(n) 节点swap的时候操作很多 会很慢
思路应该是这样 原来的list只存小于x的节点 新建一个dummy node 后面连接大于等于x的节点
最后让原list的尾节点指向dummy.next就可以了 空间复杂度O(1) 时间复杂度O(n)
public ListNode partition(ListNode head, int x) {
if (head == null || head.next == null) return head;
ListNode dummy1 = new ListNode(-1);//指向head 存小于x的节点
ListNode dummy2 = new ListNode(-1);//存大于x的节点
dummy1.next = head;
ListNode small = dummy1;
ListNode big = dummy2;
while (head != null) {
if (head.val < x) {
small = head;
} else {
small.next = head.next;
big.next = head;
big = big.next;
}
head = head.next;
}
big.next = null;
small.next = dummy2.next;
return dummy1.next;
}
solution的想法类似 但是新建了两个dummy node 分别连接小于和大于等于x的节点
代码比较整洁 但是因为原list没有使用 也没有变化 相当于把list复制了一遍 空间复杂度是O(n) 时间复杂度还是O(n)
public ListNode partition(ListNode head, int x) {
ListNode smallerHead = new ListNode(0), biggerHead = new ListNode(0);
ListNode smaller = smallerHead, bigger = biggerHead;
while (head != null) {
if (head.val < x) {
smaller = smaller.next = head;
} else {
bigger = bigger.next = head;
}
head = head.next;
}
// no need for extra check because of fake heads
smaller.next = biggerHead.next; // join bigger after smaller
bigger.next = null; // cut off anything after bigger
return smallerHead.next;
}
标红处相当于:
smaller.next = head;
smaller = smaller.next;
涉及到运算符的优先级和结合性
在java中 =从右向左计算
https://baike.baidu.com/item/%E8%BF%90%E7%AE%97%E7%AC%A6%E4%BC%98%E5%85%88%E7%BA%A7/4752611?fr=aladdin