Leetcode 第 133 场双周赛题解
Leetcode 第 133 场双周赛题解
题目1:3190. 使所有元素都可以被 3 整除的最少操作数
思路
遍历数组,累加最少操作数,即 min(num % 3, 3 - num % 3)。
代码
/*
* @lc app=leetcode.cn id=3190 lang=cpp
*
* [3190] 使所有元素都可以被 3 整除的最少操作数
*/
// @lc code=start
class Solution
{
public:
int minimumOperations(vector<int> &nums)
{
int ans = 0;
for (int &num : nums)
ans += min(num % 3, 3 - num % 3);
return ans;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 nums 的长度。
空间复杂度:O(1)。
题目2:3191. 使二进制数组全部等于 1 的最少操作次数 I
思路
分类讨论:
- 如果 nums[i]=1,无需修改,问题变成剩下 n−i-1 个数如何操作。接下来考虑 nums[i+1]。
- 如果 nums[i]=0,修改,问题变成剩下 n−i-1 个数如何操作。接下来考虑 nums[i+1]。
所以从左到右遍历数组,一边遍历一边修改。
代码
/*
* @lc app=leetcode.cn id=3191 lang=cpp
*
* [3191] 使二进制数组全部等于 1 的最少操作次数 I
*/
// @lc code=start
class Solution
{
public:
int minOperations(vector<int> &nums)
{
int n = nums.size();
int ans = 0;
for (int i = 0; i < n - 2; i++)
{
if (nums[i] == 0)
{
nums[i + 1] = (nums[i + 1] ? 0 : 1);
nums[i + 2] = (nums[i + 2] ? 0 : 1);
ans++;
}
}
if (nums[n - 2] == 0 || nums[n - 1] == 0)
return -1;
return ans;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 nums 的长度。
空间复杂度:O(1)。
题目3:3192. 使二进制数组全部等于 1 的最少操作次数 II
思路
由于 nums[i] 会被其左侧元素的操作影响,所以我们先从最左边的 nums[0] 开始思考。
分类讨论:
- 如果 nums[0]=1,无需反转,问题变成剩下 n−1 个数如何操作。接下来考虑 nums[1]。
- 如果 nums[0]=0,反转次数加一,问题变成剩下 n−1 个数(在修改次数是奇数的情况下)如何操作。接下来考虑 nums[1]。
对后续元素来说,由于反转偶数次等于没反转,所以只需考虑反转次数的奇偶性。
一般地,设反转次数的奇偶性为 k,分类讨论:
- 如果 nums[i]≠k,无需反转,接下来考虑 nums[i+1]。
- 如果 nums[i]=k,反转次数加一,接下来考虑 nums[i+1]。
代码
/*
* @lc app=leetcode.cn id=3192 lang=cpp
*
* [3192] 使二进制数组全部等于 1 的最少操作次数 II
*/
// @lc code=start
class Solution
{
public:
int minOperations(vector<int> &nums)
{
int n = nums.size();
int ans = 0;
for (int i = 0; i < n; i++)
{
if (nums[i] == 1 && ans % 2 == 1)
ans++;
if (nums[i] == 0 && ans % 2 == 0)
ans++;
}
return ans;
}
};
// @lc code=end
复杂度分析
时间复杂度:O(n),其中 n 是数组 nums 的长度。
空间复杂度:O(1)。
题目4:3193. 统计逆序对的数目
思路
题解:教你一步步思考 DP:从记忆化搜索到递推到终极优化!(Python/Java/C++/Go)
代码
#
# @lc app=leetcode.cn id=3193 lang=python3
#
# [3193] 统计逆序对的数目
#
# @lc code=start
class Solution:
def numberOfPermutations(self, n: int, requirements: List[List[int]]) -> int:
MOD = 1_000_000_007
# req[i] 是前 i 个数的逆序对个数
req = [-1] * n
req[0] = 0
for end, cnt in requirements:
req[end] = cnt
if req[0]:
return 0
@cache
def dfs(i: int, j: int) -> int:
if i == 0:
return 1
r = req[i - 1]
if r >= 0:
return dfs(i - 1, r) if r <= j <= i + r else 0
return sum(dfs(i - 1, j - k) for k in range(min(i, j) + 1)) % MOD
return dfs(n - 1, req[n - 1])
# @lc code=end
复杂度分析
时间复杂度:O(n*m*min(n,m)),其中 m=max(cnti)。
空间复杂度:O(n*m),其中 m=max(cnti)。