分隔链表(Java语言实现)

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。(详情参见https://leetcode-cn.com/problems/partition-list/)

ADT:
public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

我的思路:用一条链表存放比x小得节点,再用一条存放比x大得节点,再将两条链表合并即可。
说明:思路没毛病,但在代码实现上出了问题,苦思半天终于找到bug。

bug修改前的代码:
class Solution {
    public ListNode partition(ListNode head, int x) {
    	//声明两个链表头节点
        ListNode head1 = new ListNode(0);
        ListNode head2 = new ListNode(0);
        //声明一个在原链表上用以移动的指针
        ListNode cur = head;
        //声明两个用以移动的指针
        ListNode l1 = head1;
        ListNode l2 = head2;
        while(cur!=null){
        //当前原节点的值比x小,链接在l1,否则l2
            if(cur.val < x){
                l1.next = cur;
                l1 = l1.next;
                cur = cur.next;
            }else{
                l2 .next = cur;
                l2 = l2.next;
                cur = cur.next;
            }
        }
        //最后去除两条链表的头节点再合并两条链表
        head1 = head1.next;
        head2 = head2.next;
        l1.next = head2;
        return head1;
    }
}

思路看似没问题,但是对于一下这段代码:bug1

 l1.next = cur;
 l1 = l1.next;
 cur = cur.next;

其变化是这样(黑色为变化前,红色为变化后)
在这里插入图片描述
画图分析可知会导致各种指针指向混乱,导致后面指针寻址异常
bug1改进:

l1.next = cur;
l1 = l1.next;
cur = cur.next;
l1.next = null;//注意断开l1的链接要放在l1和cur移动之后

bug2

head1 = head1.next;
head2 = head2.next;
l1.next = head2;
return head1;

这段代码看似没毛病,实际在极端情况下会出问题,比如,如果head1.next为空(当所有节点都比x大),而l1依然指向head1所在的节点,所以此时返回的值也为空。
改进:

l1.next = head2.next;//l1链上去头后的l2链表
return head1.next;//返回去头后的l1

总结:尽量不要改变不移动的指针

以下附上完整正确代码:

public ListNode partition(ListNode head, int x) {
    ListNode head1 = new ListNode(0);
    ListNode head2 = new ListNode(0);
    ListNode cur = head;
    ListNode l1 = head1;
    ListNode l2 = head2;
    while(cur!=null){
        if(cur.val < x){
            l1.next = cur;
            cur = cur.next;
            l1 = l1.next;
            l1.next = null;
        }else{
            l2 .next = cur;
            cur = cur.next;
            l2 = l2.next;
            l2.next = null;
        }
    }
    l1.next = head2.next;
    return head1.next;
}

猜你喜欢

转载自blog.csdn.net/weixin_43695091/article/details/88412344
今日推荐