[LeetCode] 2340. Minimum Adjacent Swaps to Make a Valid Array
You are given a 0-indexed integer array nums
.
Swaps of adjacent elements are able to be performed on nums
.
A valid array meets the following conditions:
- The largest element (any of the largest elements if there are multiple) is at the rightmost position in the array.
- The smallest element (any of the smallest elements if there are multiple) is at the leftmost position in the array.
Return the minimum swaps required to make nums
a valid array.
Example 1:
Input: nums = [3,4,5,5,3,1] Output: 6 Explanation: Perform the following swaps: - Swap 1: Swap the 3rd and 4th elements, nums is then [3,4,5,3,5,1]. - Swap 2: Swap the 4th and 5th elements, nums is then [3,4,5,3,1,5]. - Swap 3: Swap the 3rd and 4th elements, nums is then [3,4,5,1,3,5]. - Swap 4: Swap the 2nd and 3rd elements, nums is then [3,4,1,5,3,5]. - Swap 5: Swap the 1st and 2nd elements, nums is then [3,1,4,5,3,5]. - Swap 6: Swap the 0th and 1st elements, nums is then [1,3,4,5,3,5]. It can be shown that 6 swaps is the minimum swaps required to make a valid array.Example 2:
Input: nums = [9] Output: 0 Explanation: The array is already valid, so we return 0.
Constraints:
1 <= nums.length <= 105
1 <= nums[i] <= 105
生成有效数组的最小交换次数。
给定一个 下标从 0 开始 的整数数组 nums。
nums 上的 相邻 元素可以进行 交换。
一个 有效 的数组必须满足以下条件:
最大的元素 (如果有多个,则为最大元素中的任何一个) 位于数组中最右边的位置。
最小的元素 (如果有多个,则为最小的任何一个元素) 位于数组的最左侧。
返回使 nums 成为有效数组所需的最少交换次数。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-adjacent-swaps-to-make-a-valid-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路是贪心。下面我根据例子仔细说一下思考过程。
注意第一个例子,最小元素是 1,那么没的说,我们只能老老实实把 1 一步一步往左边 swap,对于这个 1,他的 swap 的次数是他的 index - 0 = index 步;但是对于最大元素 5 来说,他出现了不止一次,而且因为之前涉及到跟 1 有交换位置,所以为了 swap 的步数尽量少,我们需要选择位于数组最右边的最大值,因为最右边的那个最大值是离数组最后一个 index 最近的。所以这道题我们移动的步数 = 最左边的最小值到 index = 0 的距离 + 最右边的最大值到 index = n - 1 的距离(n 是数组长度)。同时注意如果最小值在最大值右侧,在 swap 的过程中需要少算一步,因为当我们将最小值往左 swap 的时候,会经过这个最大值。
时间O(n)
空间O(1)
Java实现
1 class Solution { 2 public int minimumSwaps(int[] nums) { 3 // corner case 4 int n = nums.length; 5 if (n == 1) { 6 return 0; 7 } 8 9 // normal case 10 int min = Integer.MAX_VALUE; 11 int max = Integer.MIN_VALUE; 12 for (int i = 0; i < n; i++) { 13 if (nums[i] < min) { 14 min = Math.min(min, nums[i]); 15 } 16 if (nums[i] > max) { 17 max = Math.max(max, nums[i]); 18 } 19 } 20 21 // min和max有可能有多个,要找到最左边的min和最右边的max 22 int minIndex = 0; 23 int maxIndex = 0; 24 for (int i = 0; i < n; i++) { 25 if (nums[i] == min) { 26 minIndex = i; 27 break; 28 } 29 } 30 for (int i = n - 1; i >= 0; i--) { 31 if (nums[i] == max) { 32 maxIndex = i; 33 break; 34 } 35 } 36 37 // 如果最小值在左,最大值在右 38 if (minIndex <= maxIndex) { 39 return minIndex + (n - maxIndex); 40 } 41 // 如果最小值在右,最大值在左,需要少一步 42 return minIndex + (n - maxIndex) - 1; 43 } 44 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2022-07-20 [LeetCode] 792. Number of Matching Subsequences
2020-07-20 [LeetCode] 1180. Count Substrings with Only One Distinct Letter
2020-07-20 [LeetCode] 1100. Find K-Length Substrings With No Repeated Characters