86.分隔链表(JS)

159 阅读2分钟

分隔链表

Category Difficulty Likes Dislikes
algorithms Medium (51.56%) 106 -
Tags
Companies

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
/*
 * @lc app=leetcode.cn id=86 lang=javascript
 *
 * [86] 分隔链表
 */
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} x
 * @return {ListNode}
 */
var partition = function(head, x) {
    
};


1

image-20190807234001109

把比x小的节点放在前面.大的放后面

先不说这题的话,很容易让我们想到快速排序里的主元

先不说有没有关系,就当练习一下自己写一个快速排序

然后仔细想想这里应该运用了归并排序里的写法

function mergeSort(arr) {
	if (arr.length > 1) {
		let len = arr.length
		const left = mergeSort(arr.slice(0, len / 2))
		const right = mergeSort(arr.slice(len / 2, len))
		arr = merge(left, right)
	}
	return arr
}
function merge(left, right) {
	const ret = []
	let i = 0
	let j = 0
	while (i < left.length && j < right.length) {
		ret.push(left[i] < right[j] ? left[i++] : right[j++])
	}
	return ret.concat(i < left.length ? left.slice(i) : right.slice(j))
}

其实也没多大关系,只刚好上面有分队后再合并.

那我们完全可以使用同样的套路

创建两个链表leftright,然后便利链表,把比x小的数放在left链表,大的数放在right链表,最后合并两链表即可.

var partition = function (head, x) {
	let left = new ListNode('left') // 这里传参只是为了画图好看
	let right = new ListNode('right') // 这里传参只是为了画图好看
	let lCur = left
	let rCur = right
	while (head) {
		if (head.val < x) {
			lCur.next = head
			lCur = head
		} else {
			rCur.next = head
			rCur = head
		}
		head = head.next
	}

	lCur.next = right.next
	rCur.next = null
	return left.next
};

image-20190808123250981

后面通过判断把遍历的接点存在在新的链表上,这是不难的

但是有个细节特别容易导致出错

image-20190808123617890

我们在对节点分大小的时候,我们只是改变lCurrCur指向哪里,而未对被分类的节点进行操作

只有再再次改变lCur的时候,上次分类的节点就会被改变next

但是刚被分类的节点的next是没有改变的,注意上图中5next指向,因为当head分完时,我们已经没有再控制5节点了

此时的5节点指向的是2

那我们在合并的时候就需要注意了

image-20190808124605801

lCur.next = right.next

如果此时我们直接返回

return left.next

那这个链表是一个带环型的,与答案是不符合的

所以我们需要补充

image-20190808124700905

rCur.next = null