You are given an integer array nums. Each element in nums is 1, 2 or 3. In each operation, you can remove an element from nums. Return the minimum number of operations to make numsnon-decreasing.
Intuition: To minimize removals, we want to keep the maximum number of elements that can form a non-decreasing subsequence. The minimum operations = total length - length of longest non-decreasing subsequence.
Approach:
Use DP where dp[i][j] represents the maximum length of non-decreasing subsequence ending at index i with value j
For each element, we can either keep it (if it maintains non-decreasing order) or skip it
Transition: dp[i][nums[i]] = max(dp[i-1][k] + 1) for all valid k <= nums[i]
#include<vector>#include<algorithm>usingnamespace std;
intminimumOperations(vector<int>& nums) {
int n = nums.size();
// dp[i][j] = max length of non-decreasing subsequence ending at index i with value j
vector<vector<int>> dp(n, vector<int>(4, 0));
// Base case
dp[0][nums[0]] =1;
for (int i =1; i < n; i++) {
// Copy previous state (skip current element)
for (int j =1; j <=3; j++) {
dp[i][j] = dp[i-1][j];
}
// Include current element
int maxPrev =0;
for (int j =1; j <= nums[i]; j++) {
maxPrev = max(maxPrev, dp[i-1][j]);
}
dp[i][nums[i]] = max(dp[i][nums[i]], maxPrev +1);
}
int maxLen =0;
for (int j =1; j <=3; j++) {
maxLen = max(maxLen, dp[n-1][j]);
}
return n - maxLen;
}
classSolution {
funminimumOperations(nums: IntArray): Int {
val n = nums.size
// dp[i][j] = max length ending at index i with value j
val dp = Array(n) { IntArray(4) }
dp[0][nums[0]] = 1for (i in1 until n) {
// Copy previous state
for (j in1..3) {
dp[i][j] = dp[i-1][j]
}
// Include current element
var maxPrev = 0for (j in1..nums[i]) {
maxPrev = maxOf(maxPrev, dp[i-1][j])
}
dp[i][nums[i]] = maxOf(dp[i][nums[i]], maxPrev + 1)
}
var maxLen = 0for (j in1..3) {
maxLen = maxOf(maxLen, dp[n-1][j])
}
return n - maxLen
}
}
defminimumOperations(nums: list[int]) -> int:
n = len(nums)
# dp[i][j] = max length of non-decreasing subsequence ending at index i with value j dp = [[0] *4for _ in range(n)]
dp[0][nums[0]] =1for i in range(1, n):
# Copy previous state (skip current element)for j in range(1, 4):
dp[i][j] = dp[i-1][j]
# Include current element max_prev =0for j in range(1, nums[i] +1):
max_prev = max(max_prev, dp[i-1][j])
dp[i][nums[i]] = max(dp[i][nums[i]], max_prev +1)
max_len = max(dp[n-1][j] for j in range(1, 4))
return n - max_len
pubfnminimum_operations(nums: Vec<i32>) -> i32 {
let n = nums.len();
// dp[i][j] = max length ending at index i with value j
letmut dp =vec![vec![0; 4]; n];
dp[0][nums[0] asusize] =1;
for i in1..n {
// Copy previous state
for j in1..=3 {
dp[i][j] = dp[i-1][j];
}
// Include current element
letmut max_prev =0;
for j in1..=nums[i] asusize {
max_prev = max_prev.max(dp[i-1][j]);
}
let curr_val = nums[i] asusize;
dp[i][curr_val] = dp[i][curr_val].max(max_prev +1);
}
let max_len = (1..=3).map(|j| dp[n-1][j]).max().unwrap_or(0);
(n asi32) - (max_len asi32)
}
functionminimumOperations(nums: number[]):number {
constn=nums.length;
// dp[i][j] = max length of non-decreasing subsequence ending at index i with value j
constdp: number[][] = Array(n).fill(null).map(() => Array(4).fill(0));
dp[0][nums[0]] =1;
for (leti=1; i<n; i++) {
// Copy previous state (skip current element)
for (letj=1; j<=3; j++) {
dp[i][j] =dp[i-1][j];
}
// Include current element
letmaxPrev=0;
for (letj=1; j<=nums[i]; j++) {
maxPrev= Math.max(maxPrev, dp[i-1][j]);
}
dp[i][nums[i]] = Math.max(dp[i][nums[i]], maxPrev+1);
}
letmaxLen=0;
for (letj=1; j<=3; j++) {
maxLen= Math.max(maxLen, dp[n-1][j]);
}
returnn-maxLen;
}