算法leetcode|31. 下一个排列(rust重拳出击)

news/2024/11/20 19:44:16/

文章目录

  • 31. 下一个排列:
    • 样例 1:
    • 样例 2:
    • 样例 3:
    • 提示:
  • 分析:
  • 题解:
    • rust
    • go
    • c++
    • c
    • python
    • java


31. 下一个排列:

整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。

  • 例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3][1,3,2][3,1,2][2,3,1]

整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。

  • 例如,arr = [1,2,3] 的下一个排列是 [1,3,2]
  • 类似地,arr = [2,3,1] 的下一个排列是 [3,1,2]
  • arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。

给你一个整数数组 nums ,找出 nums 的下一个排列。

必须 原地 修改,只允许使用额外常数空间。

样例 1:

输入:nums = [1,2,3]输出:[1,3,2]

样例 2:

输入:nums = [3,2,1]输出:[1,2,3]

样例 3:

输入:nums = [1,1,5]输出:[1,5,1]

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 100

分析:

  • 面对这道算法题目,二当家的陷入了沉思。
  • 关键是要找到下一个排列的一般性规律。
  1. 首先从后向前查找第一个顺序对 (i,i+1),满足 a[i]<a[i+1]。这样「较小数」即为 a[i]。此时 [i+1,n) 必然是下降序列。

  2. 如果找到了顺序对,那么在区间 [i+1,n) 中从后向前查找第一个元素 j 满足 a[i]<a[j]。这样「较大数」即为 a[j]

  3. 交换 a[i]a[j],此时可以证明区间 [i+1,n) 必为降序。我们可以直接使用双指针反转区间 [i+1,n) 使其变为升序,而无需对该区间进行排序。


题解:

rust

impl Solution {pub fn next_permutation(nums: &mut Vec<i32>) {fn swap(nums: &mut Vec<i32>, i: usize, j: usize) {let temp = nums[i];nums[i] = nums[j];nums[j] = temp;}let mut i = nums.len() - 2;while i as i32 >= 0 && nums[i] >= nums[i + 1] {i -= 1;}if i as i32 >= 0 {let mut j = nums.len() - 1;while j as i32 >= 0 && nums[i] >= nums[j] {j -= 1;}swap(nums, i, j);}let (mut left, mut right) = (i + 1, nums.len() - 1);while left < right {swap(nums, left, right);left += 1;right -= 1;}}
}

go

func nextPermutation(nums []int)  {i := len(nums) - 2for i >= 0 && nums[i] >= nums[i+1] {i--}if i >= 0 {j := len(nums) - 1for j >= 0 && nums[i] >= nums[j] {j--}nums[i], nums[j] = nums[j], nums[i]}left, right := i+1, len(nums)-1for left < right {nums[left], nums[right] = nums[right], nums[left]left++right--}
}

c++

class Solution {
public:void nextPermutation(vector<int>& nums) {int i = nums.size() - 2;while (i >= 0 && nums[i] >= nums[i + 1]) {--i;}if (i >= 0) {int j = nums.size() - 1;while (j >= 0 && nums[i] >= nums[j]) {--j;}swap(nums[i], nums[j]);}reverse(nums.begin() + i + 1, nums.end());}
};

c

void swap(int *nums, int left, int right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;
}void nextPermutation(int *nums, int numsSize) {int i = numsSize - 2;while (i >= 0 && nums[i] >= nums[i + 1]) {--i;}if (i >= 0) {int j = numsSize - 1;while (j >= 0 && nums[i] >= nums[j]) {--j;}swap(nums, i, j);}int left = i + 1, right = numsSize - 1;while (left < right) {swap(nums, left, right);++left;--right;}
}

python

class Solution:def nextPermutation(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""i = len(nums) - 2while i >= 0 and nums[i] >= nums[i + 1]:i -= 1if i >= 0:j = len(nums) - 1while j >= 0 and nums[i] >= nums[j]:j -= 1nums[i], nums[j] = nums[j], nums[i]left, right = i + 1, len(nums) - 1while left < right:nums[left], nums[right] = nums[right], nums[left]left += 1right -= 1

java

class Solution {public void nextPermutation(int[] nums) {int i = nums.length - 2;while (i >= 0 && nums[i] >= nums[i + 1]) {--i;}if (i >= 0) {int j = nums.length - 1;while (j >= 0 && nums[i] >= nums[j]) {--j;}swap(nums, i, j);}int left = i + 1, right = nums.length - 1;while (left < right) {swap(nums, left, right);++left;--right;}}private void swap(int[] nums, int i, int j) {int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}

非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~



http://www.ppmy.cn/news/12508.html

相关文章

【pandas】17 数据处理和绘图

【pandas】17 数据处理和绘图 2023.1.16 pandas数据处理方法和绘图&#xff1a;读取数据、更改数据、时间数据等 主要参考&#xff1a;https://mofanpy.com/tutorials/data-manipulation/pandas/time 17.1运算方法 17.1.1 筛选赋值运算 就是用前面的方法对数据进行筛选&#…

如何实现外网远程登录访问jupyter notebook?

Jupyter Notebook是一个交互式笔记本&#xff0c;本质是一个 Web 应用程序&#xff0c;支持运行 40 多种编程语言&#xff0c;此前被称为 IPython notebook。Jupyter Notebook 便于创建和共享程序文档、支持实时代码、数学方程、可视化和 markdown&#xff0c;应用场景有数据清…

大数据必学Java基础(一百二十四):Maven的常见插件

文章目录 Maven的常见插件 一、编辑器插件 二、资源拷贝插件 三、tomcat插件 Maven的常见插件

经典问题:Python实现生产者消费者模式的多线程爬虫

Python实现生产者消费者模式的多线程爬虫1. 多组件的Pipeline技术架构2. 生产者消费者爬虫的架构3.多线程数据通信的queue.Queue4. 代码编写实现生产者消费者爬虫1. 多组件的Pipeline技术架构 复杂的事情一般都不会一下子做完&#xff0c;而是会分很多中间步骤一步步完成。 …

Redis缓存和数据库不一致性

先更新数据库,再删除缓存,如果删除缓存失败了,会导致数据库中是新数据,缓存中是旧数据,数据就出现了不一致。一般普通的解决方式有下面两个: 先删除缓存,再更新数据库。如果数据库更新失败了,那么数据库中是旧数据,缓存中是空的,那么数据不会不一致。读的时候缓存没…

【指针笔试题下】你知道大厂面试题的指针题是什么样的吗?快来通过这些面试题目检测一下自己吧!

目录 前言 笔试题1&#xff1a; 笔试题2&#xff1a; 笔试题3&#xff1a; 笔试题4&#xff1a; 笔试题5&#xff1a; 笔试题6&#xff1a; 笔试题7&#xff1a; 笔试题8&#xff1a; 总结&#xff1a; 博客主页&#xff1a;张栩睿的博客主页 欢迎关注&#xff1a;点赞收藏留…

springMVC的学习拦截器之验证用户登录案例

文章目录实现思路关于环境和配置文件pomspring的配置文件关于idea的通病/常见500错误的避坑实现步骤编写登陆页面编写Controller处理请求编写登录成功的页面编写登录拦截器实现思路 有一个登录页面&#xff0c;需要写一个controller访问页面登陆页面提供填写用户名和密码的表单…

基于matlab的指纹图像处理、脊线增强、脊线分割、脊线细化、细节点检测和细节点验证

需求分析对于指纹的特征提取包含几个步骤&#xff0c;脊线增强、脊线分割、脊线细化、细节点检测和细节点验证&#xff0c;本次大作业需要针对已经增强的指纹图片进行后续几个步骤&#xff0c;通过多种形态学算法进行分割、细化、细化后处理&#xff0c;找到其中的端点和分叉点…