旋转链表-双指针思想-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();
    }

}
相关推荐
zzzhpzhpzzz12 分钟前
设计模式——观察者模式
算法·观察者模式·设计模式
Mr__vantasy23 分钟前
数据结构(初阶6)---二叉树(遍历——递归的艺术)(详解)
c语言·开发语言·数据结构·算法·leetcode
IT 青年24 分钟前
数据结构 (6)栈的应用举例
数据结构
敲键盘的老乡26 分钟前
堆优化版本的Prim
数据结构·c++·算法·图论·最小生成树
码农多耕地呗29 分钟前
trie树-acwing
数据结构·c++·算法
奥利奥冰茶30 分钟前
Linux下通过DRM操作屏幕,发生行对齐 (stride)问题
算法
建模忠哥小师妹34 分钟前
2024亚太杯C题宠物行业及相关产业的发展分析和策略——成品参考思路模型代码
算法
daily_23331 小时前
数据结构——小小二叉树第三幕(链式结构的小拓展,二叉树的创建,深入理解二叉树的遍历)超详细!!!
数据结构·c++·算法
浦东新村轱天乐2 小时前
神经网络反向传播算法公式推导
神经网络·算法·机器学习
SUN_Gyq2 小时前
什么是 C++ 中的模板特化和偏特化? 如何进行模板特化和偏特化?
开发语言·c++·算法