LeetCode.面试题02.04. 分割链表
题目地址:https://leetcode-cn.com/problems/partition-list-lcci/
题目描述:将一个链表以x值为“基准”,将链表分割成小于x的节点在x节点的左边,等于x,大于x的节点在右边。
解法一:遍历将链表中的每一个节点放入链表类型的数组中,对节点进行partition操作。
时间复杂度:O(N)
额外空间复杂度:O(N)
public static class Node { public int value; public Node next; public Node(int data) { this.value = data; } } public static Node listPartition1(Node head, int pivot) { if (head == null) { return head; } Node cur = head; int i = 0; //遍历链表,记录节点个数 while (cur != null) { i++; cur = cur.next; } Node[] nodeArr = new Node[i]; i = 0; cur = head; //将节点添加到数组 for (i = 0; i != nodeArr.length; i++) { nodeArr[i] = cur; cur = cur.next; } //对数组做partition操作 arrPartition(nodeArr, pivot); //将节点连起来 for (i = 1; i != nodeArr.length; i++) { nodeArr[i - 1].next = nodeArr[i]; } nodeArr[i - 1].next = null; return nodeArr[0]; } public static void arrPartition(Node[] nodeArr, int pivot) { int small = -1; int big = nodeArr.length; int index = 0; while (index != big) { if (nodeArr[index].value < pivot) { swap(nodeArr, ++small, index++); } else if (nodeArr[index].value == pivot) { index++; } else { swap(nodeArr, --big, index); } } } public static void swap(Node[] nodeArr, int a, int b) { Node tmp = nodeArr[a]; nodeArr[a] = nodeArr[b]; nodeArr[b] = tmp; }
解法二:断链比较
利用六个变量,分别记录三个区域,小于区,等于区,大于区。
将每一个节点和目标值进行比较,小于目标值就将节点断开,将小于区的尾连接到该节点。
最后判断三个区域是否存在的情况
小于区存在,等于区不存在时,直接将小于区的Tail指向大于区的Head
小于区不存在,等于区存在,直接将等于区的Tail指向大于区的Head
最后判断三个区域的头节点是否存在,依次判断小于、等于、大于。
public ListNode partition(ListNode head, int x) { if (head == null){ return null; } ListNode smallHead = null; ListNode smallTail = null; ListNode equalHead = null; ListNode equalTail = null; ListNode bigHead = null; ListNode bigTail = null; ListNode temp =null; while (head != null){ temp = head.next; //将节点断链,重新排 head.next = null; if (head.val < x){ //如果小于区头节点==null,说明此时小于还没有节点,将新节点加入 if (smallHead == null){ smallHead = head; smallTail = head; }else { //否则,小于区已经存在节点,将新节点插入小于区尾部 smallTail.next = head; smallTail = head; } }else if (head.val == x){ 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 = temp; } //对小于区、等于区、大于区是否存在进行判断 if (smallTail != null){ //小于区存在 smallTail.next = equalHead; //此时要判断等于区是否存在,因为如果等于区不存在,就要让小于区的尾去连大于区的头 if (equalTail == null){ smallTail.next = bigHead; } } if(equalTail != null){ equalTail.next = bigHead; } // return smallHead != null ? smallHead : (equalHead != null ? equalHead : bigHead); }
学习的博客多用于在笔记中,防止笔记过于臃肿,所以将样例及运行结果放在博客中,后以超链接的形式记录在笔记中,所以有些博文过于单薄。如果有小伙伴遇到问题欢迎评论,看到就会回复,学渣一枚,加油努力。