📢前言
🚀 算法题 🚀
🌲 每天打卡一道算法题,既是一个学习过程,又是一个分享的过程😜
🌲 提示:本专栏解题 编程语言一律使用 C# 和 Java 两种进行解题
🌲 要保持一个每天都在学习的状态,让我们一起努力成为算法大神吧🧐!
🌲 今天是力扣算法题持续打卡第56天🎈!
🚀 算法题 🚀
🌲原题样例:找到所有数组中消失的数字
给你一个长度为n 的整数数组,每次操作将会使 n - 1个元素增加1。返回让数组所有元素相等的最小操作次数。
示例:
输入:nums = [1,2,3] 输出:3 解释: 只需要3次操作(注意每次操作会增加两个元素的值): [1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
示例 2:
输入:nums = [1,1,1] 输出:0
提示:
n == nums.length
1 <= nums.length <= 105
-109 <= nums[i] <= 109
答案保证符合 32-bit 整数
🌻C#方法:排序
使用return nums.Sum() - nums.Min() * nums.Length;就可以搞定,但是Sum会溢出
所以修改为以下代码,遍历一遍即可!
代码:
public class Solution { public int MinMoves(int[] nums) { int iSum = nums.Min() * nums.Length * -1; foreach (var num in nums) { iSum += num; } return iSum; } }
执行结果
通过 执行用时:156 ms,在所有 C# 提交中击败了53.85%用户 内存消耗:48.1 MB,在所有 C# 提交中击败了23.08%的用户
🌻Java 方法一:暴力法 【超时】
思路解析
首先,我们知道,为了在最小移动内使所有元素相等,我们需要在数组的最大元素之外的所有元素中执行增加。
因此,在暴力法中,我们扫描整个数组以查找最大值和最小元素。
此后,我们将 111 添加到除最大元素之外的所有元素,并增加移动数的计数。
同样,我们重复相同的过程,直到最大元素和最小元素彼此相等。
代码:
public class Solution { public int minMoves(int[] nums) { int min = 0, max = nums.length - 1, count = 0; while (true) { for (int i = 0; i < nums.length; i++) { if (nums[max] < nums[i]) { max = i; } if (nums[min] > nums[i]) { min = i; } } if (nums[max] == nums[min]) { break; } for (int i = 0; i < nums.length; i++) { if (i != max) { nums[i]++; } } count++; } return count; } }
执行结果
超时
复杂度分析
时间复杂度:O( n^2 k ),其中 n 为数组长度,k 为最大值和最小值的差。 空间复杂度:O( 1)
🌻Java 方法二:动态规划
思路解析
代码:
public class Solution { public int minMoves(int[] nums) { Arrays.sort(nums); int moves = 0; for (int i = 1; i < nums.length; i++) { int diff = (moves + nums[i]) - nums[i - 1]; nums[i] += moves; moves += diff; } return moves; } }
执行结果
通过 执行用时:13 ms,在所有 Java 提交中击败了20.05%的用户 内存消耗:38.6 MB,在所有 Java 提交中击败了92.21%的用户
复杂度分析
时间复杂度:O( nlog(n) ) 空间复杂度:O( 1)
💬总结
- 今天是力扣算法题打卡的第五十六天!
- 文章采用
C#
和Java
两种编程语言进行解题 - 一些方法也是参考力扣大神写的,也是边学习边分享,再次感谢算法大佬们
- 那今天的算法题分享到此结束啦,明天再见!