数据结构与算法(Java) 29:将单向链表按某值划分成左边小、中间相等、右边大的形式

题目 给定一个单向链表的头节点head,节点的值类型是整型,再给定一个 整数pivot。实现一个调整链表的函数,将链表调整为左部分都是值小于 pivot 的节点,中间部分都是值等于pivot的节点,右部分都是值大于 pivot的节点。 除这个要求外,对调整后的节点顺序没有更多的要求。 例如:链表9->0->4->5- >1,pivot=3。 调整后链表可以是1->0->4->9->5,也可以是0->1->9->5->4。总 之,满 足左部分都是小于3的节点,中间部分都是等于3的节点(本例中这个部 分为空),右部分都是大于3的节点即可。对某部分内部的节点顺序不做 要求。

进阶 在原问题的要求之上再增加如下两个要求。 在左、中、右三个部分的内部也做顺序要求,要求每部分里的节点从左 到右的 顺序与原链表中节点的先后次序一致。 例如:链表9->0->4->5->1,pivot=3。 调整后的链表是0->1->9->4->5。 在满足原问题要求的同时,左部分节点从左到 右为0、1。在原链表中也 是先出现0,后出现1;中间部分在本例中为空,不再 讨论;右部分节点 从左到右为9、4、5。在原链表中也是先出现9,然后出现4, 最后出现5。 如果链表长度为N,时间复杂度请达到O(N),额外空间复杂度请达到O(1)。

思路 (1)若不考虑稳定性以及空间复杂度,则可以借用荷兰国旗方法。首先将链表节点内容依次存放到数组中,再利用荷兰国旗方法进行调整,最后将数组内容依次串成链表即可。

        (2)若考虑稳定性并限制复杂度,则需要设置3条链表:small(用于存放小于pivot的所有数值)、equal(用于存放等于equal的所有数值)、big(用于存放大于pivot的所有数值)。遍历链表,若当前数值小于pivot,则将该数值嫁接到small链表下;若当前数值等于pivot,则将该数值嫁接到equal链表下;若当前数值大于pivot,则将该数值嫁接到big链表下。最后,依次将small、equal、big链表连接到一次。注意连接时是否存在空链表的情况。

package algorithm.section4;

public class SmallerEqualBigger {
    public static class Node{
        int value;
        Node next;

        public Node(int value){
            this.value = value;
        }
    }

    public static Node method1(Node head, int num){
        if (head == null) return null;
        Node flag = head;
        int length = 0;
        while (flag != null){
            length++;
            flag = flag.next;
        }
        Node[] arr = new Node[length];
        flag = head;
        int i = 0;
        while (flag != null){
            arr[i++] = flag;
            flag = flag.next;
        }
        sort(arr, num);
        int cur = 0;
        while (cur + 1 < arr.length){
            arr[cur].next = arr[cur + 1];
            cur++;
        }
        arr[cur].next = null;
        return arr[0];
    }

    public static void sort(Node[] arr, int num){
        int i = -1;
        int j = arr.length;
        int current = 0;
        while (current < j){
            if (arr[current].value < num){
                swap(arr, current, i + 1);
                i++;
                current++;
            } else if (arr[current].value == num){
                current++;
            } else {
                swap(arr, current, j - 1);
                j--;
            }
        }
    }

    public static void swap(Node[] arr, int a, int b){
        Node f = arr[a];
        arr[a] = arr[b];
        arr[b] = f;
    }

    public static Node method2(Node head, int pivot){
        Node next =  head.next;

        Node smallH = null;
        Node smallT = null;
        Node equalH = null;
        Node equalT = null;
        Node bigH = null;
        Node bigT = null;
        while (head != null){
            next = head.next;
            head.next = null;
            if (head.value < pivot){
                if (smallH == null) {
                    smallH = head;
                    smallT = head;
                }
                else {
                    smallT.next = head;
                    smallT = smallT.next;
                }
            } else if (head.value == pivot) {
                if (equalH == null) {
                    equalH = head;
                    equalT = head;
                }
                else {
                    equalT.next = head;
                    equalT = equalT.next;
                }
            } else {
                if (bigH == null) {
                    bigH = head;
                    bigT = head;
                }
                else {
                    bigT.next = head;
                    bigT = bigT.next;
                }
            }
            head = next;
        }
        if (smallT != null) {
            smallT.next = equalT == null ? bigH : equalH;
            equalT.next = equalT == null ? null : bigH;
            return smallH;
        } else if (equalT != null){
            equalT.next = bigH;
            return equalH;
        } else {
            return bigH;
        }
    }

    public static void print(Node head){
        while (head != null) {
            System.out.print(head.value + " ");
            head = head.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Node head1 = new Node(7);
        head1.next = new Node(9);
        head1.next.next = new Node(1);
        head1.next.next.next = new Node(8);
        head1.next.next.next.next = new Node(5);
        head1.next.next.next.next.next = new Node(2);
        head1.next.next.next.next.next.next = new Node(5);
        print(head1);
//        head1 = method1(head1, 4);
        head1 = method2(head1, 5);
        print(head1);

    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值