反转部分单向链表

描述

给定一个单链表,在链表中把第 L 个节点到第 R 个节点这一部分进行反转。

示例1

输入:

5
1 2 3 4 5
1 3

输出:

3 2 1 4 5

解题思路:

想要反转第from到第to这部分的链表,必须要找到from节点前一个fPre节点,以及to节点后一个节点tPos节点。找到后,对第from到第to这部分的链表进行反转,再接上fPre节点和tPos节点。

实现过程:

1、利用len记录链表的长度,每走一个节点就加一。如果当len等于from-1,就说明此时的fPre就是当前node1,同理,tPos等于to+1时,tPos就是当前node1。

while(node1!=null){
     len++;
     fPre=len==from-1?node1:fPre;
     tPos=len==to+1?node1:tPos;
     node1=node1.next;
}

2、判断边界条件

if(from>to||from<1||to>len){
    return head;
}

3、初始化node1和node2位置

node1初始化是反转部分链表的第一个节点。

node2初始化为反转部分链表的第二个节点。

fPre等于空的话,就将head作为node1,否则就将fPre的下一个节点作为node1

node1的下一个节点就是node2

  • 反转前先将node1指向tPos节点(反转后就是部分链表的最后一个节点)
  • 进行反转
  • 反转后将fPre节点指向部分链表最后一个节点node1(反转后就是部分链表的第一个节点)
import java.util.Scanner;

class Node{
    public int value;
    public Node next;
    public Node(int value){
        this.value=value;
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        String[] n=in.nextLine().split(" ");
        String[] num=in.nextLine().split(" ");
        String[] LR=in.nextLine().split(" ");
        
        Node node=transForNode(num);
        
        node=reversePart(node,Integer.parseInt(LR[0]),Integer.parseInt(LR[1]));
        
        show(node);
    }
    //打印链表
    public static void show(Node head){
        while(head!=null){
            System.out.print(head.value+" ");
            head=head.next;
        }
        System.out.println();
    }
    //数组转链表
    public static Node transForNode(String[] nums) {
        Node head = new Node(Integer.parseInt(nums[0]));
        Node cur = head;
        for(int i = 1; i < nums.length; i++) {
            cur.next = new Node(Integer.parseInt(nums[i]));
            cur = cur.next;
        }
        return head;
    }
    
    public static Node reversePart(Node head,int from,int to){
        int len=0;
        Node node1=head;
        Node fPre=null;
        Node tPos=null;
        while(node1!=null){
            len++;
            fPre=len==from-1?node1:fPre;
            tPos=len==to+1?node1:tPos;
            node1=node1.next;
        }
        if(from>to||from<1||to>len){
            return head;
        }
        node1= fPre==null?head:fPre.next;//fPre前一个是空,head节点是node1,不为空,node1就是fPre的下一个
        Node node2=node1.next;//node2初始化为node1的下一个
        node1.next=tPos;//将node1指向tPos
        Node next=null;//定义一个next
        while(node2!=tPos){
            next=node2.next;
            node2.next=node1;
            node1=node2;
            node2=next;
        }
        if(fPre!=null){//fPre不为空就返回head
            fPre.next=node1;//fPre连到反转后node1节点
            return head;
        }
        return node1;//fPre为空返回反转完的第一个节点node1
    }
}






 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值