Leetcode-86. Partition List

题目描述(中等难度)

在这里插入图片描述
感觉中文翻译的比较晦涩,有点不好理解。梳理一下,大致意思是给定一个链表,根据给定的阈值,我们将链表分成两部分,链表左边的部分数字全部小于区分点X,链表右边的部分数字全部大于区分点X。类似快速排序的思想。最终分成两类:122 435.

解法一

主要分为两部分:

1.根据原链表,定义尾指针tail。首先遍历链表,找到第一个大于等于分区点x的节点,我们将tail指向这个节点的前边。如果满足条件,则跳出这个循环,否则一直遍历下去。

2.找出小于区分点的节点,并把节点添加到tail后面,并更新tail值。

package Partition_List;

class ListNode {
    int val;
    ListNode next;
    ListNode(int val) { 
    	this.val = val; 
    	}
 }
	 
public class Partition_List {
	
	
	public static ListNode partition(ListNode head, int x) {
	    ListNode dummy = new ListNode(0);
	    dummy.next = head;
	    ListNode tail = null; 
	    head = dummy;
	    //找到第一个大于等于分区点的节点,tail 指向它的前边
	    while (head.next != null) {
	        if (head.next.val >= x) {
	            tail = head; 
	            head = head.next;
	            break;
	        }else {
	            head = head.next;
	        }
	    }
	    while (head.next != null) {
	        //如果当前节点小于分区点,就把它插入到 tail 的后边
	        if (head.next.val < x) {
	            //拿出要插入的节点
	            ListNode move = head.next;
	            //将要插入的结点移除
	            head.next = move.next;
	            //将 move 插入到 tail 后边
	            move.next = tail.next; 
	            tail.next = move; 
	            //更新 tail
	            tail = move;
	        }else{
	            head = head.next;
	        }

	    } 
	    return dummy.next;
	}
	public static void main(String args[]) {
		ListNode head=new ListNode(1);
		ListNode p=head;
		p.next=new ListNode(4);
		p=p.next;
		p.next=new ListNode(3);
		p=p.next;
		p.next=new ListNode(2);
		p=p.next;
		p.next=new ListNode(5);
		p=p.next;
		p.next=new ListNode(2);
		int x=3;
		ListNode ans=partition(head,x);
		while(ans!=null) {
			System.out.println(ans.val);
			ans=ans.next;
		}
	}
}

时间复杂度:O(n)。需要遍历链表。

空间复杂度:O(1)。没有空间开销。

解法二

采用官方给出的 solution 。

新创建两个链表,一个链表min保存小于分区点的数,另一个链表max保存大于等于分区点的数,然后把两个链表结合在一起就可以了。

package Partition_List;

public class partition_List2 {
	
	public ListNode partition_List2(ListNode head, int x) { 
	    //小于分区点的链表
	    ListNode min_head = new ListNode(0);
	    ListNode min = min_head;
	    //大于等于分区点的链表
	    ListNode max_head = new ListNode(0);
	    ListNode max = max_head;

	    //遍历整个链表
	    while (head != null) {  
	        if (head.val < x) {
	            min.next = head;
	            min = min.next;
	        } else { 
	            max.next = head;
	            max = max.next;
	        }

	        head = head.next;
	    } 
	    max.next = null;  //这步不要忘记,不然链表就出现环了
	    //两个链表接起来
	    min.next = max_head.next;

	    return min_head.next;
	}
}

时间复杂度:O(n)。

空间复杂度:O(1)。

总结

基本的链表知识点考察。感觉这类题目侧重于理解,如果读懂了题目的意思,做出来也就是水到渠成的事情了。

参考

1.https://zhuanlan.zhihu.com/p/69255463

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安替-AnTi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值