旋转链表-双指针思想-LeetCode61

题目要求:给定链表的头结点,旋转链表,将链表每个节点向右移动K个位置。

示例:

输入:head = 1,2,3,4,5, k=2

输出:4,5,1,2,3

双指针思想:

先用双指针策略找到倒数K的位置,也就是(1,2,3)和4,5)两个序列,之后再将两个链表拼接成(4,5,1,2,3}就行了。
具体思路是:

因为k有可能大于链表长度,所以首先获取一下链表长度len,如果然后k=k % len,如果k == 0,则不用旋转,直接返回头结点。否则:

1、快指针先走k步

2、慢指针和快指针一起走

3、快指针走到链表尾部时,慢指针所在位置刚好是要断开的地方。把快指针指向的节点连到原链表头部,慢指针指向的节点断开和下一节点的联系

4、返回结束时慢指针指向节点的下一节点

java 复制代码
import java.util.*;

public class RotateRight_旋转数组 {

    public static void main(String[] args) {
        //int[] a = {1, 2, 3, 4, 5};
        ArrayList<Integer> lst = new ArrayList<>();

        //输入
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        Scanner input = new Scanner(s);
        while(input.hasNextInt()){
            lst.add(input.nextInt());
        }
        Integer[] a = lst.toArray(new Integer[lst.size()]);



        ListNode nodeA = initLinkedList(a); //数组初始化为链表
        ListNode nodeB = initLinkedList2(lst); //集合初始化为链表
        ListNode node = rotateRight(nodeB, 2);  //开始旋转
        System.out.println(toString(node));
    }


    //定义链表节点
    static class ListNode{
        public int val;
        public ListNode next;

        ListNode(int x){
            val = x;
            next = null;
        }
    }

    //数组初始化链表
    public static ListNode initLinkedList(Integer[] a){
        ListNode head = null, cur = null;

        for (int i = 0; i < a.length; i++){
            ListNode newNode = new ListNode(a[i]);
            if (i==0){
                head = newNode;
                cur = newNode;
            }else{
                cur.next = newNode;
                cur = cur.next;
            }
        }
        return head;
    }

    //集合初始化链表
    public static ListNode initLinkedList2(ArrayList a){
        ListNode head = null, cur = null;

        for (int i = 0; i < a.size(); i++){
            ListNode newNode = new ListNode((Integer) a.get(i));
            if (i==0){
                head = newNode;
                cur = newNode;
            }else{
                cur.next = newNode;
                cur = cur.next;
            }
        }
        return head;
    }

    //开始旋转
    public static ListNode rotateRight(ListNode head, int k) {
        if (head == null || k == 0) {
            return head;
        }
        ListNode temp = head;
        ListNode fast = head;
        ListNode slow = head;
        int len = 0;
        //链表的长度
        while (head != null) {
            head = head.next;
            len++;
        }
        //如果能整除,则直接返回该链表
        if (k % len == 0) {
            return temp;
        }

        while ((k % len) > 0) {
            k--;
            fast = fast.next;
        }
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }
        ListNode res = slow.next;
        slow.next = null;
        fast.next = temp;
        return res;
    }

    //输出链表
    public static String toString(ListNode head) {
        ListNode current = head;
        //StringBuilder可以用来拼接字符串
        StringBuilder sb = new StringBuilder();
        while(current !=null){
            sb.append(current.val).append("\t");
            current = current.next;
        }
        return sb.toString();
    }

}
相关推荐
沫璃染墨17 分钟前
从零入门数据结构与算法(一):复杂度分析——从算法效率到时间与空间复杂度
c语言·开发语言·数据结构·笔记·算法·飞书
熊猫钓鱼>_>1 小时前
面试出现 606 次的第 K 大,被拆成三个问题问
算法·面试·职场和发展·校招·面经·oj·ai生成
xuxigifxfh1 小时前
牛客:BISHI2 【模板】栈的操作
java·开发语言·windows·算法
aqiu1111111 小时前
【C++算法打怪专栏】LeetCode 402. 移掉 K 位数字(单调栈 + 贪心)
c++·算法·leetcode
糖果豆豆2 小时前
对象是字段,还是关系?集合论和范畴论吵了三十年,答案是两个都对
算法·架构
第六种自由2 小时前
[路飞]_Leetcode 22. 括号生成
javascript·算法·leetcode
isyoungboy2 小时前
事件驱动状态机与循环扫描状态机:两种计算模型的比较研究
算法·状态机
行者全栈架构师2 小时前
【鸿蒙心迹】从手机到平板、折叠屏——多端适配自查清单与踩坑实录(HarmonyOS 7.x)
前端·算法·架构
longlongzihan3 小时前
LeetCode 24.两两交换链表中的节点:虚拟头结点与指针
算法·leetcode·链表
residual_fan3 小时前
基于控制感知域对抗网络的变工况故障诊断:从控制系统与运行状态协同的角度建立模型
人工智能·算法·数据挖掘·数据分析