链表11:链表的分化

题目:对于一个链表,我们需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面,同时保证两类结点内部的位置关系不变。

给定一个链表的头结点head,同时给定阈值val,请返回一个链表,使小于等于它的结点在前,大于等于它的在后,保证结点值不重复。

测试样例:

{1,4,2,5},3

{1,2,4,5}

思路一:将链表元素放到一个数组中,在数组中实现分化,将小于val的值移动到左边,将大于val的值移动到右边,最后再将其串联成为链表即可。类似于荷兰国旗问题,使用了额外的空间复杂度。

思路二:将单链表分化成为3条链表,遍历链表,小于val的结点形成一条链表list1,等于val的结点形成一条链表list2,大于val的结点形成一条链表list3,然后再将list1,list2,list3连接起来返回头结点即可。

{1620,1134,861,563,1},1134对应输出应该为:{1134,861,563,1,1620}你的输出为:{861,563,1,1134,1620}

注意理解清楚题目的意思:即整个链表应该分成2个部分而不是3个部分,对于分界值val,遍历链表,将小于或者等于val的结点组成链表list1,将大于val的结点放到链表list2,于是即使有等于val的结点,塔门依然是分隔开的,而不是全部集中在一起。思路还是一样的,只是对于题目的理解要准确。

这里要注意几个点:关于引用关系的深入理解:

非常关键点:千万注意这里:list1、list2的最后一个结点都是引用了list,而list是一整条链表,因此list1,list2在需要保留的结点之后还会拖带这list上面的结点,这是不准确的因此必须将list1,list2尾巴后面list链表的值切断。总结:如果新的链表list1需要对原链表摸个结点之后的全部结点进行引用那么就直接将list赋值给新链表即可,如果新链表list1只需要原链表list上面的某几个结点,那么在list1从list上获取到最后一个需要的结点之后就要手动将list1的next置为null,来切断关联。

非常关键点:当前resultList指向的是head1链表的头结点,要使得head2能够连接到其尾部需要将resultList指针移动到head1尾部。

public class Divide {
    	public ListNode listDivide(ListNode head, int val) {
        //特殊的输入
        if(head==null) return null;
        //构造3条链表,每条链表都要记住头结点
        ListNode head1=new ListNode(-1);
        ListNode head2=new ListNode(-1);
        ListNode list1=head1;
        ListNode list2=head2;
        //对输入的主链表进行遍历
        ListNode list=head;
        while(list!=null){
            if(list.val<=val){
                list1.next=list;
                list1=list1.next;
            }else if(list.val>val){
                list2.next=list;
                list2=list2.next;
            }
             list=list.next;
        }
/*非常关键点①:千万注意这里:list1、list2的最后一个结点都是引用了list,而list是一整条链表,因此list1,list2在需要保留的结点之后还会拖带这list上面的结点,这是不准确的因此必须将list1,list2尾巴后面list链表的值切断。总结:如果新的链表list1需要对原链表摸个结点之后的全部结点进行引用那么就直接将list赋值给新链表即可,如果新链表list1只需要原链表list上面的某几个结点,那么在list1从list上获取到最后一个需要的结点之后就要手动将list1的next置为null,来切断关联。*/
        if(list1.next!=null)  list1.next=null;
        if(list2.next!=null)  list2.next=null;
        
        /*已经得到list1,list2,list3,将其连接起来即可;注意:只有不为空的才可以被连接;如果直接连接list1,list2,list3,那么要对list1,list2,list3中
        某个项为null进行判断,存在很多种情况,十分麻烦;所以解决方案是重新建立一个链表resultList,将不为null的链表连接到resultList即可。*/
        ListNode dummy=new ListNode(-1);
        ListNode resultList=dummy;
        //说明小于链存在,将其连接到resultList上
        if(head1.next!=null){
        	resultList.next=head1.next;
        	//非常关键点②:当前resultList指向的是head1链表的头结点,要使得head2能够连接到其尾部需要将resultList指针移动到head1尾部
        	while(head1.next!=null){
        		resultList=resultList.next;
        		head1=head1.next;
        	}
        }
        //说明等于链存在,将其连接到resultList上
        if (head2.next!=null) {
        	resultList.next=head2.next;
        	while(head2.next!=null){
        		resultList=resultList.next;
        		head2=head2.next;
        	}
		}
        //说明大于链存在,将其连接到resultList上
        return dummy.next;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值