链表内指定区间反转&&划分链表-

1.链表内指定区间反转 - js

描述
将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 1→4→3→2→5→NULL.

示例1
输入:{1,2,3,4,5},2,4
返回值:{1,4,3,2,5}
思路:链表的题思路简单编码麻烦,老是在弥缝子
1.根据题目给定的区间将链表切割成三段,并且将区间内的一段反转之后再次链接即可

代码实现

function reverseBetween( head ,  m ,  n ) {
    // write code here
    if(!head || !head.next || m == n) return head
    // 反转链表
    function reserve(root){
        let node = root
        let prev = node
        while(node){
            prev = node
            node = node.next
            if(prev === root){
                prev.next = null
            }else{
               prev.next = root
            }
            root = prev
        }
        return root
    }
    let count = 0
    let frist = null
    if(m > 1){
        frist = head
    }
    let mid = null
    let end = null
    let node = head
    let fristEnd = null
    while(node){
        count ++
        if(count === m - 1){
            fristEnd = node
            node = node && node.next
            count ++
            fristEnd.next = null
        }
        if(count === m){
            mid = node
        }
        if(count === n){
            end = node && node.next
            node.next = null
        }
        node = node && node.next
    }
    mid = reserve(mid)
    // 链接链表
    if(frist){
        node = frist
        while(node && node.next) node = node.next
        node.next = mid
    }
    node = mid
    while(node && node.next) node = node.next
    node.next = end
    return frist ? frist : mid
}

2.划分链表-js

描述
给出一个长度为 n 的单链表和一个值 x ,单链表的每一个值为 listi ,请返回一个链表的头结点,要求新链表中小于 x 的节点全部在大于等于 x 的节点左侧,并且两个部分之内的节点之间与原来的链表要保持相对顺序不变。

例如:
给出 1→4→3→2→5→2 和 x = 3
返回 1→2→2→4→3→5

示例1
输入:{1,4,3,2,5,2},3
返回值:{1,2,2,4,3,5}
思路:找到第一个比目标值大的节点maxNode之后,暂停当前指针,新创建一个指针向后遍历找到第一个比目标值小的节点minNode,
插入到当前指针所指的maxNode节点前面,需要注意的是插入后需要将遍历指针向前移动一位以保证遍历指针一直指向当前的这个最大节点maxNode,
因为后面所有的minNode节点需要全部插入到这个节点前面,才能保证大于等于目标值的节点顺序不变。

代码实现

function partition( head ,  x ) {
    // write code here
    let node = head
    let minNode = null
    let maxNode = null
    let prevMaxNode = null
    let prevMinNode = null
    while(node){
        if(node.val >= x){
            maxNode = node
            let newNode = node
            while(newNode){
                if(newNode.val < x){
                    minNode = newNode
                    break
                }
                prevMinNode = newNode
                newNode = newNode && newNode.next
            }
        }
        if(maxNode && minNode){
            prevMinNode.next = minNode && minNode.next
            minNode.next = node
            // 这里需要注意一下 如果第一个节点的值就比目标值大的话是没有前置节点的所以要判断一下
            if(prevMaxNode) {
                prevMaxNode.next = minNode 
                // 并且在凭借完列表后遍历指针需要向前走一步,因为后面所有比目标值小的节点将全部插在这个节点后面
                node = prevMaxNode
            }else {
                head = minNode
                node = head
            }
            maxNode = null
            minNode = null
        }
        prevMaxNode = node
        node = node && node.next
    }
    return head
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值