【leetcode】面试题 02.04. 分割链表

编写程序以 x 为基准分割链表,使得所有小于 x 的节点排在大于或等于 x 的节点之前。如果链表中包含 x,x 只需出现在小于 x 的元素之后(如下所示)。分割元素 x 只需处于“右半部分”即可,其不需要被置于左右两部分之间。

示例:

输入: head = 3->5->8->5->10->2->1, x = 5
输出: 3->1->2->10->5->5->8

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode partition(ListNode head, int x) {
        if(head == null || head.next == null ){
            return head;
        }
        ListNode h = head, p = head;

        LinkedList<ListNode> list = new LinkedList<>();
        while(head != null ) {
            if(head.val < x){
                list.add(head);
            }
            head = head.next;
        }
        head = p;
        while(head != null){
            if(head.val >= x){
                list.add(head);
            }
            head = head.next;
        }
        h = list.get(0);
        for(int i=0; i< list.size()-1; i++){
            p = list.get(i);
            p.next = list.get(i+1);
            p = p.next;
        }
        p.next = null;
        return h;
    }
}

上面这个揭发太挫了,看了题解,发现可以用双指针来做,前面的指针一直指着大于等于target的节点的前一个节点,后一个指针一直判断其指向接待你的后一个节点是小于target还是大于等于target,如果是前者,那么就将该节点移到前面指针后面,如果是后者那么就不管,继续遍历即可。新的题解如下:

class Solution {
    public ListNode partition(ListNode head, int x) {
        if(head == null || head.next == null ){
            return head;
        }
        ListNode pre = new ListNode(-1);
        pre.next = head;
        ListNode front = pre;
        boolean flag = false;
        // 首先将front指向第一个大于等于x的节点前面
        while(front.next != null && front.next.val < x){
            front = front.next;
            flag = true;
        }
        // front指向的节点大于等于x
        if(!flag){
            front = front.next;
        }

        while(front.next != null ) {
            if(front.next.val >= x){
                front = front.next;
            }else{
                ListNode moveNode = front.next;
                front.next = moveNode.next;
                ListNode firstBig = pre.next;
                pre.next = moveNode;
                moveNode.next = firstBig;
            }
        }
        return pre.next;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值