005-反转部分单向链表

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 Solution02 {
	public SingleNode reversePart(SingleNode head, int from, int to) {
		//len记录链表中节点的个数
		int len = 0;
		//cur临时变量,记录当前正在遍历的链表
		SingleNode cur = head;
		//fPre记录需要反转部分的前一个节点
		SingleNode fPre = null;
		//tPos记录需要反转部分的后一个节点
		SingleNode tPos = null;
		//遍历链表记录链表总结点个数,并找到fPre和tPos的正确位置
		while(cur != null) {
			len++;
			fPre = (len == from - 1) ? cur : fPre;
			tPos = (len == to + 1) ? cur : tPos;
			cur = cur.next;
		}
		//边界条件判断
		if(from < 1 || from > to || to > len) {
			//满足以上条件说明链表不满足部分反转的条件,则返回原头节点
			return head;
		}
		//fPre为空则说明要反转的部分包含头结点,头结点就是要反转部分的第一个节点,pre记录要反转部分的第一个节点
		SingleNode pre = (fPre == null) ? head : fPre.next;
		//cur记录当前节点
		cur = pre.next;
		//将tPose赋值为pre的后继节点,pre完成反转
		pre.next = tPos;
		//定义节点记录后继节点
		SingleNode next = null;
		while(cur != tPos) {
			//先用next记录后继节点,防止调整指针后找不到原链表
			next = cur.next;
			//调整当前节点的后继节点
			cur.next = pre;
			//pre向后移动一个位置,记录当前遍历的节点
			pre = cur;
			//cur向后移动一个位置,记录下一个需要遍历的节点
			cur = next;	
		}
		if(fPre != null) {
			//将fPre与需要调整的部分连接起来
			fPre.next = pre;
			//说明需要调整的部分不包括头结点,只需返回旧的头结点
			return head;
		}
		//否则说明反转部分包括头结点,返回新的头结点,新的头结点为翻转部分的最后一个节点
		return pre;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值