Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/2263.html
2263. Make Array Non-decreasing or Non-increasing
Description
You are given a 0-indexed integer array nums
. In one operation, you can:
- Choose an index
i
in the range0 <= i < nums.length
- Set
nums[i]
tonums[i] + 1
ornums[i] - 1
Return the minimum number of operations to make nums
non-decreasing or non-increasing.
Example 1:
Input: nums = [3,2,4,5,0] Output: 4 Explanation: One possible way to turn nums into non-increasing order is to: - Add 1 to nums[1] once so that it becomes 3. - Subtract 1 from nums[2] once so it becomes 3. - Subtract 1 from nums[3] twice so it becomes 3. After doing the 4 operations, nums becomes [3,3,3,3,0] which is in non-increasing order. Note that it is also possible to turn nums into [4,4,4,4,0] in 4 operations. It can be proven that 4 is the minimum number of operations needed.
Example 2:
Input: nums = [2,2,3,4] Output: 0 Explanation: nums is already in non-decreasing order, so no operations are needed and we return 0.
Example 3:
Input: nums = [0] Output: 0 Explanation: nums is already in non-decreasing order, so no operations are needed and we return 0.
Constraints:
1 <= nums.length <= 1000
0 <= nums[i] <= 1000
Follow up: Can you solve it in O(n*log(n))
time complexity?
Solutions
-
class Solution { public int convertArray(int[] nums) { return Math.min(solve(nums), solve(reverse(nums))); } private int solve(int[] nums) { int n = nums.length; int[][] f = new int[n + 1][1001]; for (int i = 1; i <= n; ++i) { int mi = 1 << 30; for (int j = 0; j <= 1000; ++j) { mi = Math.min(mi, f[i - 1][j]); f[i][j] = mi + Math.abs(j - nums[i - 1]); } } int ans = 1 << 30; for (int x : f[n]) { ans = Math.min(ans, x); } return ans; } private int[] reverse(int[] nums) { for (int i = 0, j = nums.length - 1; i < j; ++i, --j) { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; } return nums; } }
-
class Solution { public: int convertArray(vector<int>& nums) { int a = solve(nums); reverse(nums.begin(), nums.end()); int b = solve(nums); return min(a, b); } int solve(vector<int>& nums) { int n = nums.size(); int f[n + 1][1001]; memset(f, 0, sizeof(f)); for (int i = 1; i <= n; ++i) { int mi = 1 << 30; for (int j = 0; j <= 1000; ++j) { mi = min(mi, f[i - 1][j]); f[i][j] = mi + abs(nums[i - 1] - j); } } return *min_element(f[n], f[n] + 1001); } };
-
class Solution: def convertArray(self, nums: List[int]) -> int: def solve(nums): n = len(nums) f = [[0] * 1001 for _ in range(n + 1)] for i, x in enumerate(nums, 1): mi = inf for j in range(1001): if mi > f[i - 1][j]: mi = f[i - 1][j] f[i][j] = mi + abs(x - j) return min(f[n]) return min(solve(nums), solve(nums[::-1]))
-
func convertArray(nums []int) int { return min(solve(nums), solve(reverse(nums))) } func solve(nums []int) int { n := len(nums) f := make([][1001]int, n+1) for i := 1; i <= n; i++ { mi := 1 << 30 for j := 0; j <= 1000; j++ { mi = min(mi, f[i-1][j]) f[i][j] = mi + abs(nums[i-1]-j) } } ans := 1 << 30 for _, x := range f[n] { ans = min(ans, x) } return ans } func reverse(nums []int) []int { for i, j := 0, len(nums)-1; i < j; i, j = i+1, j-1 { nums[i], nums[j] = nums[j], nums[i] } return nums } func abs(x int) int { if x < 0 { return -x } return x } func min(a, b int) int { if a < b { return a } return b }