【路飞】-算法练习——86. 分隔链表

354 阅读1分钟

作为一个常年摸鱼的前端er,也是时候让自己练习一下一些基础算法了,今天第一天,嗯...话不多说,直接开整!

题目】: 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。

partition.jpg

输入: head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

思路】:分割链表很常见的一种操作,分两半比大小,然后接起来。定义两个空链表,比给定值大的放一起,比给定值小的放一起,然后小数值链表最后指向大数值链表

【代码】:

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} x
 * @return {ListNode}
 */
var partition = function(head, x) {
    if(!head || head.val === null) return null

    let left = new ListNode(),right = new ListNode(),l = left,r = right

    while(head!=null){
        if(head.val < x) {
            left.next = head
            left= left.next
        }else{
            right.next = head
            right = right.next
        }
        head = head.next
    }
    left.next = r.next
    right.next = null
    r.next = null
    return l.next
};

js刷算法涉及到链表就比较奇奇怪怪,代码在力扣上是可以直接运行,但是如果想在本地Node环境测试,那就还需要一些额外的操作:

// 数组转链表
function arrayList(ary) {
  if(!ary.length) {
      return null
  }

  var node
  var head = {val: ary[0], next: null}
  var pnode = head  //pnode变量用来保存前一个节点

  for(var i = 1; i < ary.length; i++) {
      node = {val: ary[i], next:null}
      pnode.next = node   //将前一个节点的next指向当前节点
      pnode = node   //将node赋值给pnode
  }

  return head
}

// 链表转数组
function listArray(head) {
  if(!head) {
      return []
  }
  var result = [head.val]
  var restValues = listArray(head.next)
  return result.concat(restValues)
}

试一下:

const example = [0,8,1,3,4,5,7,2,4,3,2,5,2]
test(`${example} => `, () => {
  expect(listArray(partition(arrayList([0,8,1,3,4,5,7,2,4,3,2,5,2]), 3))).toStrictEqual([0,1,2,2,2,8,3,4,5,7,4,3,5])
})

image.png

完工,睡觉!