大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!
精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。
博客主页💖:知识汲取者的博客
LeetCode热题100专栏🚀:LeetCode热题100
Gitee地址📁:知识汲取者 (aghp) - Gitee.com
Github地址📁:Chinafrfq · GitHub
题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台
PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激
解法一:模拟
这里是参考了LeetCode官方的题解,这种方式本质就是模拟,难点在于边界值的判断,判断是否应该取等,很值得深思。这段代码,理解起来也不难,画一下草图就出来的
这里的话,给出几个例子,相信就能明白了:
/**
* @author ghp
* @title 下一个排列
*/
class Solution {
public void nextPermutation(int[] nums) {
// 从后往前寻找出 左小右大 的两个元素
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
// 判断当前排列是否是最大排列
if (i >= 0) {
// 当前排列不是最大的(存在 左小右大 的两个元素)
// 从后往前寻找出比nums[i]要大的元素(此时nums[i]后的元素是降序排列的)
int j = nums.length - 1;
while (j > i && nums[i] >= nums[j]) {
j--;
}
// 交换nums[i]和nums[j],使得当前排列恰好比上一个排列大一点,中间没有其它排列
swap(nums, i, j);
}
// 将nums[i]后面的元素进行反转,使得整个排列能够尽可能小
reverse(nums, i);
}
private void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
private void reverse(int[] nums, int i) {
int l = i + 1;
int r = nums.length - 1;
while (l < r){
swap(nums, l++, r--);
}
}
}
复杂度分析:
其中 n n n 为数组中元素的个数
待定