• 每日一题 为了工作 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+"	");
                head = head.next;
            }
            System.out.println();
        }
    }

    *运行结果

     

     

  • 相关阅读:
    CI框架主题切换的功能
    centos7 编译安装 php7.4
    单用户登陆demo-后者挤到前者,类似QQ
    nginx 负载均衡的配置
    PHP计算每月几周,每周的开始结束日期
    Centos7 编译安装PHP7
    TP 3.2.3 接入PHPMailer
    外部js引用vue实例环境的方式
    linux常用命令
    计算机中的二级制
  • 原文地址:https://www.cnblogs.com/walxt/p/12558558.html
Copyright © 2020-2023  润新知