代码拉取完成,页面将自动刷新
同步操作将从 doocs/leetcode 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
给你一个下标从 0 开始长度为 n
的整数数组 nums
。
从 0
到 n - 1
的数字被分为编号从 1
到 3
的三个组,数字 i
属于组 nums[i]
。注意,有的组可能是 空的 。
你可以执行以下操作任意次:
x
并改变它的组。更正式的,你可以将 nums[x]
改为数字 1
到 3
中的任意一个。你将按照以下过程构建一个新的数组 res
:
1
,2
和 3
中的元素 依次 连接以得到 res
。如果得到的 res
是 非递减顺序的,那么我们称数组 nums
是 美丽数组 。
请你返回将 nums
变为 美丽数组 需要的最少步数。
示例 1:
输入:nums = [2,1,3,2,1] 输出:3 解释:以下三步操作是最优方案: 1. 将 nums[0] 变为 1 。 2. 将 nums[2] 变为 1 。 3. 将 nums[3] 变为 1 。 执行以上操作后,将每组中的数字排序,组 1 为 [0,1,2,3,4] ,组 2 和组 3 都为空。所以 res 等于 [0,1,2,3,4] ,它是非递减顺序的。 三步操作是最少需要的步数。
示例 2:
输入:nums = [1,3,2,1,3,3] 输出:2 解释:以下两步操作是最优方案: 1. 将 nums[1] 变为 1 。 2. 将 nums[2] 变为 1 。 执行以上操作后,将每组中的数字排序,组 1 为 [0,1,2,3] ,组 2 为空,组 3 为 [4,5] 。所以 res 等于 [0,1,2,3,4,5] ,它是非递减顺序的。 两步操作是最少需要的步数。
示例 3:
输入:nums = [2,2,2,2,3,3] 输出:0 解释:不需要执行任何操作。 组 1 为空,组 2 为 [0,1,2,3] ,组 3 为 [4,5] 。所以 res 等于 [0,1,2,3,4,5] ,它是非递减顺序的。
提示:
1 <= nums.length <= 100
1 <= nums[i] <= 3
我们定义 $f[i][j]$ 表示将前 $i$ 个数变成美丽数组,并且第 $i$ 个数变成 $j+1$ 的最少操作次数。那么答案就是 $\min(f[n][0], f[n][1], f[n][2])$。
我们可以枚举第 $i$ 个数变成 $j+1$ 的所有情况,然后取最小值。这里我们可以用滚动数组优化空间复杂度。
时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
f = g = h = 0
for x in nums:
ff = gg = hh = 0
if x == 1:
ff = f
gg = min(f, g) + 1
hh = min(f, g, h) + 1
elif x == 2:
ff = f + 1
gg = min(f, g)
hh = min(f, g, h) + 1
else:
ff = f + 1
gg = min(f, g) + 1
hh = min(f, g, h)
f, g, h = ff, gg, hh
return min(f, g, h)
class Solution {
public int minimumOperations(List<Integer> nums) {
int[] f = new int[3];
for (int x : nums) {
int[] g = new int[3];
if (x == 1) {
g[0] = f[0];
g[1] = Math.min(f[0], f[1]) + 1;
g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1;
} else if (x == 2) {
g[0] = f[0] + 1;
g[1] = Math.min(f[0], f[1]);
g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1;
} else {
g[0] = f[0] + 1;
g[1] = Math.min(f[0], f[1]) + 1;
g[2] = Math.min(f[0], Math.min(f[1], f[2]));
}
f = g;
}
return Math.min(f[0], Math.min(f[1], f[2]));
}
}
class Solution {
public:
int minimumOperations(vector<int>& nums) {
vector<int> f(3);
for (int x : nums) {
vector<int> g(3);
if (x == 1) {
g[0] = f[0];
g[1] = min(f[0], f[1]) + 1;
g[2] = min({f[0], f[1], f[2]}) + 1;
} else if (x == 2) {
g[0] = f[0] + 1;
g[1] = min(f[0], f[1]);
g[2] = min(f[0], min(f[1], f[2])) + 1;
} else {
g[0] = f[0] + 1;
g[1] = min(f[0], f[1]) + 1;
g[2] = min(f[0], min(f[1], f[2]));
}
f = move(g);
}
return min({f[0], f[1], f[2]});
}
};
func minimumOperations(nums []int) int {
f := make([]int, 3)
for _, x := range nums {
g := make([]int, 3)
if x == 1 {
g[0] = f[0]
g[1] = min(f[0], f[1]) + 1
g[2] = min(f[0], min(f[1], f[2])) + 1
} else if x == 2 {
g[0] = f[0] + 1
g[1] = min(f[0], f[1])
g[2] = min(f[0], min(f[1], f[2])) + 1
} else {
g[0] = f[0] + 1
g[1] = min(f[0], f[1]) + 1
g[2] = min(f[0], min(f[1], f[2]))
}
f = g
}
return min(f[0], min(f[1], f[2]))
}
function minimumOperations(nums: number[]): number {
let f: number[] = new Array(3).fill(0);
for (const x of nums) {
const g: number[] = new Array(3).fill(0);
if (x === 1) {
g[0] = f[0];
g[1] = Math.min(f[0], f[1]) + 1;
g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1;
} else if (x === 2) {
g[0] = f[0] + 1;
g[1] = Math.min(f[0], f[1]);
g[2] = Math.min(f[0], Math.min(f[1], f[2])) + 1;
} else {
g[0] = f[0] + 1;
g[1] = Math.min(f[0], f[1]) + 1;
g[2] = Math.min(f[0], Math.min(f[1], f[2]));
}
f = g;
}
return Math.min(...f);
}
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
f = [0] * 3
for x in nums:
g = [0] * 3
if x == 1:
g[0] = f[0]
g[1] = min(f[:2]) + 1
g[2] = min(f) + 1
elif x == 2:
g[0] = f[0] + 1
g[1] = min(f[:2])
g[2] = min(f) + 1
else:
g[0] = f[0] + 1
g[1] = min(f[:2]) + 1
g[2] = min(f)
f = g
return min(f)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。