合并有序链表问题

1.合并两个有序链表

    public NodeList mergeNodeList(NodeList node1,NodeList node2){
        NodeList headfirst = new NodeList();
        NodeList head = headfirst;
        while(node1!=null||node2!=null){
            if (node1!=null&&node2!=null) {
                if (node1.value < node2.value) {
                    head.next = node1;
                    node1 = node1.next;
                } else if (node1.value > node2.value) {
                    head.next = node2;
                    node2 = node2.next;
                } else {
                    //这里代码的顺序不能写反
                    head.next = node1;
                    node1 = node1.next;
                    head = head.next;
                    head.next = node2;
                    node2 = node2.next;
                    //错误写法
//                    head.next = node1;
//                    head = head.next;
                    //这里直接让node1指向node2,导致node1 = node1.next;的结果是node2的链表
//                    head.next = node2;
//                    node1 = node1.next;
//                    node2 = node2.next;
                }
                head = head.next;
            }else if (node2!=null){
                head.next=node2;
                node2=node2.next;
                head=head.next;
            }else{
                head.next=node1;
                node2=node1.next;
                head=head.next;
            }
        }
        return headfirst.next;
    }

这种写法比较臃肿,我们可以把遍历到相同的情况与另外其他一种合并,一次判断只处理其中一个重复节点

public NodeList mergeNodeList(NodeList node1, NodeList node2) {
        NodeList firstHead = new NodeList();
        NodeList head = firstHead;
        while (node1 != null && node2 != null) {
            if (node1.value <= node2.value) {
                head.next = node1;
                node1 = node1.next;
            } else {
                head.next = node2;
                node2 = node2.next;
            }
            head = head.next;
        }
        //只剩下一个链表,因为是有序链表不用排序,直接将剩下的链表的当前节点直接拼接在后面
        head.next = node1 == null ? node2 : node1;
        return firstHead.next;
    }

2.合并K个有序链表

第一种两两合并

public NodeList mergeNodeLists(NodeList[] nodeLists) {
        NodeList currentNode = null;
        for (NodeList node : nodeLists) {
            currentNode = this.mergeNodeList(currentNode, node);
        }
        return currentNode;
    }

第二种利用二分思想合并

public NodeList mergeNodeLists(List<NodeList> nodeLists) {
        List<NodeList> newList ;
        int length = nodeLists.size();
        while (length!=1){
            newList = new ArrayList<>();
            if (length%2==0){
                for (int i = 0; i <= length/2-1; i++) {
                    newList.add(this.mergeNodeList(nodeLists.get(length/2-1-i),nodeLists.get(length/2+i)));
                    length = newList.size();
                }
            }else {
                nodeLists.add(new NodeList());
                for (int i = 0; i <= length/2-1; i++) {
                    newList.add(this.mergeNodeList(nodeLists.get(length/2-1-i),nodeLists.get(length/2+i)));
                    length = newList.size();
                }
            }
            nodeLists = newList;
        }
        return nodeLists.get(0);
    }

这个代码看起来不太美观,优化后的代码如下

public NodeList mergeNodeLists(List<NodeList> nodeLists) {
        List<NodeList> newList;
        int length = nodeLists.size();
        while (length != 1) {
            newList = new ArrayList<>();
            for (int i = 0; i < length / 2; i++) {
                newList.add(i, this.mergeNodeList(nodeLists.get(i), nodeLists.get(i + length / 2)));
            }
            //如果nodeLists的长度为奇数,把最后一个加入newList,下一次循环处理
            if (length % 2 != 0) {
                newList.add(nodeLists.get(length - 1));
            }
            length = newList.size();
            nodeLists = newList;
        }
        return nodeLists.get(0);
    }

3.一道无聊的好题

给你两个链表,它们包含的节点数分别为M和N,现在要把一个链表的第a,第b节点中间的节点全部截掉,把另外一个节点拼接进去

代码入下:

   public NodeList mergeInBetween(NodeList node1,NodeList node2,int a,int b) {
        NodeList headA = node1;
        NodeList headB = node1;
        NodeList lastNode = node2;
        int indexA=0;
        int indexB=0;
        while(indexA!=a){
            headA=headA.next;
            indexA++;
        }
        while(indexB!=b){
            headB=headB.next;
            indexB++;
        }
        while(lastNode.next!=null){
            lastNode=lastNode.next;
        }
        if (a<b){
            lastNode.next=headB;
            headA.next=node2;
        }else {
            lastNode.next=headA;
            headB.next=node2;
        }
        return node1;
    }

本章的有序链表学习完毕

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值