博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
链表11:链表的分化
阅读量:3732 次
发布时间:2019-05-22

本文共 2802 字,大约阅读时间需要 9 分钟。

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

给定一个链表的头结点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;    }}

转载地址:http://dvzin.baihongyu.com/

你可能感兴趣的文章
hash文件校验
查看>>
tornado异步协程
查看>>
Tornado的WebSocket
查看>>
基于tornado实现聊天室
查看>>
django外部脚本调用django环境
查看>>
12306抢票软件
查看>>
进程池
查看>>
线程池
查看>>
Flask入门到精通
查看>>
使用celery实现订单超时取消
查看>>
守护进程实际用途: 监控报活
查看>>
python实现图书管理系统
查看>>
python面试题总结
查看>>
一文搞定ros
查看>>
使用vscode改flask端口,ip不生效
查看>>
PostgreSQL入门
查看>>
Protobuf
查看>>
python异步之asyncio
查看>>
Oracle VM VirtualBOX下克隆虚拟机镜像
查看>>
一文搞懂Typescript
查看>>