020-按照左右半区的方式重新组合单链表

package com.my.util;
/**
 * 单向链表节点
 * */
public class SingleNode {
	public int value;
	public SingleNode next;
	public SingleNode(int data){
		this.value = data;
	}
}

package com.my.suanfa;

import com.my.util.SingleNode;

/**
 * 按照左右半区的方式重新组合单链表
 * 时间复杂度O(N),额外空间复杂度O(1)
 * 将单链表根据左右两区拆分为两个单链表
 * */
public class Solution17 {
	public void relocate(SingleNode head) {
		//如果链表为空或者只有一个节点,则不需要重新组合
		if(head == null || head.next == null) {
			return;
		}
		//遍历链表找到中间位置
		SingleNode mid = head;
		SingleNode right = head.next;
		while(right.next != null && right.next.next != null) {
			mid = mid.next;
			right = right.next.next;
		}
		//mid的后继节点就是右区的第一个节点
		right = mid.next;
		//此时mid是左区的最后一个节点,则将mid的后继节点设为空
		mid.next = null;
		//此时已经找到了左区的第一个节点和右区的第一个节点,开始合并左右两区
		mergeLR(head, right);
	}
	/**
	 * 合并左右两区
	 * left左区第一个节点
	 * right右区第一个节点
	 * */
	public void mergeLR(SingleNode left, SingleNode right) {
		SingleNode next = null;
		while(left.next != null) {
			//next记录右区未合并部分
			next = right.next;
			right.next = left.next;
			left.next = right;
			left = right.next;
			right = next;
		}
		//此时left是左区的最后一个节点,如果总的节点数为偶数,则右区还剩一个节点,
		//如果总结点数为奇数,右区还剩两个节点,无论右区剩一个节点还是两个节点,
		//都是连接在左区最后一个节点的后面,因此这最后一个节点要特殊处理
		left.next = right;
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值