Dummy节点和尾插法 练习题

demo下载地址

题目描述:

给出一个链表和一个值x,要求将链表中所有小于x的值放到左边,所有大于x的值放到右边,并且原链表的节点顺序不能变?

例如:

例如:1->5->3->2->4->2,给定 x=3 ,则返回为 1->2->2->5->3->4

思路:

对于这道题目我们要先处理左边即小于X的节点,在处理右边即大于X的节点,最后在将两边左右链接起来。

思考

我们如何处理左边,如何处理右边,处理完后如何在链接起来

1)首先将题目进行简化:
给出一个链表和一个X值,要求只保留链表中所有小于X的值原链表的节点顺序不能变
例如:例如:1->5->3->2->4->2,给定 x=3 ,则返回为 1->2->2

只要采用尾插法,遍历链表将小于X的值得节点接入新的链表即可

代码

func p_getLeftList(_ head: ListNode?,_ x: Int) -> ListNode? {
        
        let dummy = ListNode.init(val: 0)
        var per = dummy , node = head
        while node != nil {
            if node!.val < x{
                per.next = node
                per = node!
            }
            node = node!.next
        }
        //防止构成环
        per.next = nil
        return dummy.next
        
    }

验证

 @objc func getLeftList()
    {
        
        let one = ListNode.init(val: 1)
        let two = ListNode.init(val: 5)
        let three = ListNode.init(val: 3)
        let four = ListNode.init(val: 2)
        let five = ListNode.init(val: 4)
        let six = ListNode.init(val: 2)
        
        one.next = two
        two.next = three
        three.next = four
        four.next = five
        five.next = six

        let result = self.p_getLeftList(one, 3)
        
        var dummy = result
        while dummy != nil {
            print("node val: \(dummy!.val)")
            dummy = dummy?.next
        }
        
    }

现在解决了左边,右边也是同样处理,接着只要让左边的尾结点指向右边的头节点即可

答案代码

 func p_partition(_ head: ListNode?,_ x: Int) -> ListNode? {
        //引入Dummy 节点
        let prevDummy = ListNode.init(val: 0),postDummy = ListNode.init(val: 0)
        var prev = prevDummy, post = postDummy
        
        var node = head
        
        //用尾插法处理左边和右边
        
        while node != nil {
            if node!.val < x {
                prev.next = node
                prev = node!
            }else{
                post.next = node
                post = node!
            }
            node = node!.next
        }
        //防止循环引用
        post.next = nil
        //左右拼接
        
        prev.next = postDummy.next
        
        
        return prevDummy.next
    }

测试:

 func partition()  {
        let one = ListNode.init(val: 1)
        let two = ListNode.init(val: 5)
        let three = ListNode.init(val: 3)
        let four = ListNode.init(val: 2)
        let five = ListNode.init(val: 4)
        let six = ListNode.init(val: 2)
        
        one.next = two
        two.next = three
        three.next = four
        four.next = five
        five.next = six
        
        let result = self.p_partition(one, 3)
        
        var dummy = result
        while dummy != nil {
            print("node val: \(dummy!.val)")
            dummy = dummy?.next
        }
    }

注意:

这里的 post.next = nil 是为了防止链表循环指向构成环,这时必须的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值