每日一题 为了工作 2020 0324 第二十二题
/**
* 题目:将单向链表按某值划分成左边小、中间相等、右边大的形式(进阶)
*
* 要求:
* 给定一个单向链表的头节点 head, 节点的值类型是整型, 再给定一个整数 pivot。实现
*一个调整链表的函数, 将链表调整为左部分都是值小于pivot的节点, 中间部分都是值等于pivot
*的节点, 右部分都是值大于pivot的节点。除这个要求外, 对调整后的节点顺序没有更多的要求。
*例如: 链表 9->0->4->5->1, pivot=3。同时区域节点要求有序,即为 0->1->4->5->9。
* 给定的时间复杂度为O(N),额外空间复杂度为 O(1),
*
* 分析:
* 由于对每部分都增加了节点顺序要求, 同时时间复杂度仍然为O(N),额外空间复杂度为0(1)。
*既然额外空间复杂度为0(1), 说明实现时只能使用有限的几个变量来完成所有的调整。
*
*进阶解法的具体过程如下:
*1.将原链表中的所有节点依次划分进三个链表, 三个链表分别为small代表左部分,equal代表中间部分, big代表右部分。
*
*例如, 链表7->9-> 1->8->5->2->5, pivot=5。在划分之后, small、equal、big分别为:
* small: 1->2->null
* equal: 5->5->null
* big: 7->9->8->null
*2. 将 small、equal和 big三个链表重新串起来即可。
*3. 整个过程需要特别注意对null节点的判断和处理。
* @author 雪瞳
*
*/
*代码
public class Node {
public int value;
public Node next;
public Node(int data) {
this.value=data;
}
}
public class ListPart {
private ListPart list = null;
public Node listPartNode(Node head,int pivot) {
Node smallHead = null;
Node smallTail = null;
Node equalHead= null;
Node equalTail= null;
Node bigHead= null;
Node bigTail= null;
Node currentNext= null;
//将原链表内的所有节点都放到三个链表内
while(head!=null) {
currentNext = head.next;
head.next=null;
if(head.value < pivot) {
if(smallHead == null) {
smallHead = head;
smallTail = head;
}else {
smallTail.next=head;
smallTail=head;
}
}else if(head.value ==pivot) {
if(equalHead==null) {
equalHead= head;
equalTail = head;
}else {
equalTail.next=head;
equalTail = head;
}
}else {
if(bigHead==null) {
bigHead=head;
bigTail=head;
}else {
bigTail.next=head;
bigTail=head;
}
}
head =currentNext;
}
//链表内部排序
list = new ListPart();
if(smallHead!=null) {
smallHead=list.listArraySwap(smallHead);
}
if(equalHead!=null) {
equalHead=list.listArraySwap(equalHead);
}
if(bigHead!=null) {
bigHead=list.listArraySwap(bigHead);
}
currentNext = smallHead;
while(currentNext.next!=null) {
currentNext=currentNext.next;
}
smallTail = currentNext;
//小的和相等的连接
if(smallTail !=null) {
if(equalHead!=null) {
equalHead=smallTail.next;
}else {
equalHead=smallTail;
equalTail=smallTail;
}
}
//连接所有节点
if(equalTail!=null) {
equalTail.next=bigHead;
}
return smallHead != null?smallHead:(equalHead!=null)?equalHead:bigHead;
}
public Node listArraySwap(Node head) {
Node current =null;
Node nodeArray[] = null;
int length =0;
current =head;
//获取链表长度
while(current!=null) {
length++;
current=current.next;
}
//将链表内元素存入到数组中
nodeArray = new Node[length];
current=head;
for(int i=0;i<nodeArray.length;i++) {
nodeArray[i]=current;
current=current.next;
}
//排序
int i=0;
int j=0;
int currentValue = 0;
int currentNextValue =0;
for(i=0;i<length;i++) {
currentValue=nodeArray[i].value;
for(j=0;j<length;j++) {
currentNextValue=nodeArray[j].value;
if(currentValue<currentNextValue) {
swapElement(nodeArray, i, j);
}
}
}
//连接节点
for(i=1;i!=length;i++) {
nodeArray[i-1].next=nodeArray[i];
}
nodeArray[length-1].next=null;
head = nodeArray[0];
return head;
}
public void swapElement(Node nodeArray[],int a,int b) {
Node transElement = nodeArray[a];
nodeArray[a] = nodeArray[b];
nodeArray[b] = transElement;
}
}
import java.util.Random;
import java.util.Scanner;
public class TestListPart {
public static void main(String[] args) {
ListPart list = new ListPart();
TestListPart test = new TestListPart();
//获取初始信息
Random rand = new Random();
Scanner sc = new Scanner(System.in);
System.out.println("请输入链表长度");
int K = sc.nextInt();
System.out.println("请输入位置元素值");
int privot = sc.nextInt();
//随机生成链表
Node nodes[]=new Node[K];
for(int i=0;i<nodes.length;i++) {
nodes[i]=new Node(rand.nextInt(20)+1);
}
for(int i =0;i<nodes.length-1;i++) {
nodes[i].next=nodes[i+1];
}
Node head = nodes[0];
//test
test.showNode(head);
Node partNode = list.listPartNode(head, privot);
test.showNode(partNode);
}
public void showNode(Node head) {
System.out.println("链表内的元素如下所示...");
while(head != null) {
System.out.print(head.value+"\t");
head = head.next;
}
System.out.println();
}
}
*运行结果