【Leetcode】旋转系列(数组、矩阵、链表、函数、字符串)

本文总结了LeetCode中的旋转系列问题,包括189.轮转数组、面试题01.07.旋转矩阵、剑指Offer24.反转链表、61.旋转链表、396.旋转函数和796.旋转字符串。分别介绍了问题的思路和高效解决方案,并给出了相应的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【Leetcode】旋转系列题目总结如下:

旋转系列问题

189. 轮转数组

1.题目描述

leetcode链接:189. 轮转数组
在这里插入图片描述
在这里插入图片描述

2.思路分析

根据k来轮转数组,要求空间复杂度为O(1),因此需要在原数组上进行反转,因此可以先反转整个数组,再把前k个反转,再把后n-k个反转。

需要注意的是:k大于nums.length的情况,需要用k对nums.length取模

3.参考代码

class Solution {
    public void rotate(int[] nums, int k) {
        int n = nums.length;
        k = k % n;
        reverse(nums, 0, n - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, n - 1);
    }
    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int tmp = nums[start];
            nums[start++] = nums[end];
            nums[end--] = tmp;
        }
    }
}
面试题 01.07. 旋转矩阵

1.题目描述

leetcode链接:面试题 01.07. 旋转矩阵

在这里插入图片描述

2.思路分析

每次交换菱形四个顶点。

3.参考代码

class Solution {
    public void rotate(int[][] matrix) {
        // 交换菱形四个顶点
        int n = matrix.length;
        int start = 0, end = n - 1;
        while (start < end) {
            for (int i = 0; i < end - start; i++) {
                int tmp = matrix[start][start + i];
                matrix[start][start + i] = matrix[end - i][start];
                matrix[end - i][start] = matrix[end][end - i];
                matrix[end][end - i] = matrix[start + i][end];
                matrix[start + i][end] = tmp;
            }
            start++;
            end--;
        }
    }
}
剑指 Offer 24. 反转链表

1.题目描述

leetcode链接:剑指 Offer 24. 反转链表
在这里插入图片描述

2.思路分析

方法一:迭代法(双指针)
在这里插入图片描述
方法二:递归

使用递归法遍历链表,当越过尾节点后终止递归,在回溯时修改各节点的 next 引用指向。

3.参考代码

方法一:迭代法(双指针)

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode dumpy = null;
        while (head != null) {
            ListNode tmp = head.next;
            head.next = dumpy;
            dumpy = head;
            head = tmp;
        }
        return dumpy;
    }
}

方法二:递归

class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        ListNode node = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return node;
    }
}
61. 旋转链表

1.题目描述

leetcode链接:61. 旋转链表

在这里插入图片描述

2.思路分析

先统计链表长度,同时将链表首尾相连,然后对k进行取模,判断旋转点。然后旋转点以后的点赋值为新节点,再把旋转点之后的点赋值为null即可。

3.参考代码

class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null || head.next == null || k == 0) return head;
        ListNode p = head;
        int n = 1;  // 统计链表长度
        while (p.next != null) {
            n++;
            p = p.next;
        }
        k %= n;
        if (k == 0) return head;
        p.next = head;  // 首尾相连
        // 找到旋转点
        for (int i = 0; i < n - k; i++) {
            p = p.next;
        }
        ListNode newHead = p.next;  // 将旋转点后面的点赋值给新的头节点
        p.next = null; // 将该旋转点点之后赋为null
        return newHead;
    }
}
396. 旋转函数

1.题目描述

leetcode链接:396. 旋转函数
在这里插入图片描述

2.思路分析

递推公式 f[0] = f[0]
f[i] = f[i - 1] - sum(A) + A[i - 1] * N

3.参考代码

class Solution {
    public int maxRotateFunction(int[] nums) {
        int n = nums.length;
        if (n == 0) return 0;
        int sum = Arrays.stream(nums).sum();
        int[] f = new int[n];  // 旋转函数
        for (int i = 0; i < n; i++) {
            f[0] += i * nums[i];
        }
        int res = f[0];
        for (int i = 1; i < n; i++) {
            f[i] = f[i - 1] - sum + n * nums[i - 1];
            res = Math.max(f[i], res);
        }
        return res;
    }
}
796. 旋转字符串

1.题目描述

leetcode链接:796. 旋转字符串

在这里插入图片描述

2.思路分析

方法一:子字符串

只需比较一下两个字符串的长度,然后判断A + A中是否存在B就ok,因为A + A中已经包含了所有可能的移动情况

方法二:模拟

首先,如果 s 和 goal 的长度不一样,那么无论怎么旋转,s 都不能得到 goa,返回 false。在长度一样(都为 n)的前提下,假设 s 旋转 i 位,则与 goal 中的某一位字符 goal[j] 对应的原 s 中的字符应该为 s[(i + j)  mod  n]。在固定 i 的情况下,遍历所有 j,若对应字符都相同,则返回 true。否则,继续遍历其他候选的 i。若所有的 i 都不能使 s 变成 goal,则返回 false。

3.参考代码

方法一:子字符串

class Solution {
    public boolean rotateString(String s, String goal) {
        return s.length() == goal.length() && (s + s).contains(goal);
    }
}

方法二:模拟

class Solution {
    public boolean rotateString(String s, String goal) {
        int m = s.length(), n = goal.length();
        if (m != n) {
            return false;
        }
        for (int i = 0; i < n; i++) {
            boolean flag = true;
            for (int j = 0; j < n; j++) {
                if (s.charAt((i + j) % n) != goal.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return true;
            }
        }
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值