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

}
相关推荐
uesowys7 分钟前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
ValhallaCoder13 分钟前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮16 分钟前
AI 视觉连载1:像素
算法
智驱力人工智能1 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥2 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风2 小时前
代码随想录第十五天
数据结构·算法·leetcode
XX風2 小时前
8.1 PFH&&FPFH
图像处理·算法
NEXT062 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
代码游侠3 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
想进个大厂3 小时前
代码随想录day37动态规划part05
算法