每日一题 为了工作 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();
    }
}

*运行结果

 

 

posted @ 2020-03-24 13:44  雪瞳  阅读(153)  评论(0编辑  收藏  举报