[程序员代码面试指南]链表问题-将单向链表按某值划分成左边小,中间相等,右边大的形式

题意

  • 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个整数k。实现一个调整链表的函数,将链表调整为左部分都是值小于k的节点,中间部分都是值等于k的节点,右部分都是值大于k的节点。
  • 在左、中、右三个部分的内部也做顺序要求,要求每部分里的节点从左到右的顺序与原链表中节点的先后次序一致。
  • 如果链表长度为N,要求时间复杂度O(N),空间复杂度O(1)。

题解

  • 遍历一遍链表,把其变为新的三条链表,分别存储与题目对应的三种节点,最后把三条链表连起来即可,注意节点为空的情况。
  • 时间复杂度O(N),额外空间复杂度O(1)。

代码

public class Main {
	public static void main(String args[]) {	
		Node head=init();//测试
		Node newHead=listPartition(head,3);	
		printList(newHead);//测试
	}
	
	public static Node listPartition(Node head,int k) {
		Node cur=head;
		//三个链表的头尾
		Node sHead=null;
		Node sTail=null;
		Node eHead=null;
		Node eTail=null;
		Node bHead=null;
		Node bTail=null;
		
		//把原链表的节点连到对应的链表
		while(cur!=null) {
			if(cur.val<k) {
				if(sHead==null) {
					sHead=cur;
					sTail=cur;
				}
				else {
					sTail.next=cur;
					sTail=cur;
				}
			}
			else if(cur.val==k) {
				if(eHead==null) {
					eHead=cur;
					eTail=cur;
				}
				else {
					eTail.next=cur;
					eTail=cur;
				}
			}
			else {
				if(bHead==null) {
					bHead=cur;
					bTail=cur;
				}
				else {
					bTail.next=cur;
					bTail=cur;
				}
			}
			cur=cur.next;
		}
		sTail.next=null;
		eTail.next=null;
		bTail.next=null;
		
	    //连接三条链表
		if(sHead!=null) {
			if(eHead!=null) {
				sTail.next=eHead;
				eTail.next=bHead;
			}
			else {
				sTail.next=bHead;
			}
			return sHead;
		}
		else if(eHead!=null){
			eTail.next=bHead;
			return eHead;
		}
		else {
			return bHead;
		}
	}
	
	//测试用,初始化
	public static Node init() {
		Node n1=new Node(4);
		Node n2=new Node(3);
		Node n3=new Node(1);
		Node n4=new Node(7);
		Node n5=new Node(5);
		n1.next=n2;
		n2.next=n3;
		n3.next=n4;
		n4.next=n5;				
		return n1;
	}
	
	//测试用,打印链表
	public static void printList(Node head) {
		Node p=head;
		while(p!=null) {
			System.out.println(p.val);
			p=p.next;
		}
	}
}

posted on 2019-05-20 21:54  coding_gaga  阅读(109)  评论(0编辑  收藏  举报

导航