diff --git "a/topic03/submit/LC1186_\351\203\221\346\235\203\345\263\260.cpp" "b/topic03/submit/LC1186_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..af7971e59d6eabd02b06acbffb53a6eff0e3ff2d --- /dev/null +++ "b/topic03/submit/LC1186_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,22 @@ +#include +using namespace std; + +// 【题目】LC1186.删除一次得到子数组的最大和 +// 【难度】中等 +// 【提交】2025.9.27 https://leetcode.cn/problems/maximum-subarray-sum-with-one-deletion/submissions/666504151 +// 【标签】数组、动态规划、第153场周赛 + +// 动态规划 +class Solution { +public: + int maximumSum(vector& arr) { + int n = arr.size(); + int dp0 = arr[0], dp1 = 0, res = arr[0]; + for(int i = 1;i < n;i++){ + dp1 = max(dp1 + arr[i], dp0); + dp0 = max(dp0 + arr[i], arr[i]); // 等效于dp0 = max(dp0, 0) + arr[i]; + res = max(res, max(dp0, dp1)); + } + return res; + } +}; diff --git "a/topic03/submit/LC1480_\351\203\221\346\235\203\345\263\260.cpp" "b/topic03/submit/LC1480_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..6106ab23db8734bd2dc2caa39ed2242b7146496f --- /dev/null +++ "b/topic03/submit/LC1480_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,32 @@ +#include +using namespace std; + +// 【题目】LC1480.一维数组的动态和 +// 【难度】简单 +// 【提交】2025.9.27 https://leetcode.cn/problems/running-sum-of-1d-array/submissions/666338271 +// 【标签】数组、前缀和、第193场周赛 + +// 方法1: +class Solution { +public: + vector runningSum(vector& nums) { + vector res; + int sum = 0; + for(int num : nums){ + sum += num; + res.push_back(sum); + } + return res; + } +}; + +// 方法2: +class Solution { +public: + vector runningSum(vector& nums) { + for(int i = 1;i < nums.size();i++){ + nums[i] += nums[i - 1]; + } + return nums; + } +}; diff --git "a/topic03/submit/LC1685_\351\203\221\346\235\203\345\263\260.cpp" "b/topic03/submit/LC1685_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..a70704f6703ebf8989cb1cfade339ae3d29abd20 --- /dev/null +++ "b/topic03/submit/LC1685_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,27 @@ +#include +using namespace std; + +// 【题目】LC1685.有序数组中差绝对值之和 +// 【难度】中等 +// 【提交】2025.9.27 https://leetcode.cn/problems/sum-of-absolute-differences-in-a-sorted-array/submissions/666509644 +// 【标签】数组、数学、前缀和、第41场双周赛 + +const auto _ = std::cin.tie(nullptr) -> sync_with_stdio(false); + +class Solution { +public: + vector getSumAbsoluteDifferences(vector& nums) { + int n = nums.size(); + vector prefix(n); + prefix[0] = nums[0]; + for(int i = 1;i < n;i++){ + prefix[i] = prefix[i-1] + nums[i]; + } + vector res(n); + res[0] = prefix[n-1] - prefix[0] - (n - 1)*nums[0]; + for(int i = 1;i < n;i++){ + res[i] = prefix[n-1] - prefix[i] - prefix[i-1] - (n-1 - 2*i) * nums[i]; + } + return res; + } +}; diff --git "a/topic03/submit/LC2134_\351\203\221\346\235\203\345\263\260.cpp" "b/topic03/submit/LC2134_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..849852a0a1dae89a09b7f5239791268fb51e8160 --- /dev/null +++ "b/topic03/submit/LC2134_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,56 @@ +#include +using namespace std; + +// 【题目】LC2134.最少交换次数来组合所有的1 II +// 【难度】中等 +// 【提交】2025.9.27 https://leetcode.cn/problems/minimum-swaps-to-group-all-1s-together-ii/submissions/666518450 +// 【标签】数组、滑动窗口、第275场周赛 + +// 方法1:前缀和 +const auto _ = std::cin.tie(nullptr) -> sync_with_stdio(false); + +class Solution { +public: + int minSwaps(vector& nums) { + int n = nums.size(); + vector prefix(n); + prefix[0] = nums[0]; + int cnt1 = nums[0], cnt2 = 1 - nums[0]; + for(int i = 1;i < n;i++){ + prefix[i] = prefix[i-1] + nums[i]; + cnt1 += nums[i]; + cnt2 += 1 - nums[i]; + } + if(cnt1 == n || cnt2 == n) return 0; + int res = cnt1 - prefix[cnt1 - 1]; + for(int i = 1;i < n - cnt1 + 1;i++){ + res = min(res, cnt1 - (prefix[i + cnt1 - 1] - prefix[i - 1])); + } + res = min(res, prefix[cnt2 - 1]); + for(int i = 1;i < n - cnt2 + 1;i++){ + res = min(res, prefix[i + cnt2 - 1] - prefix[i - 1]); + } + return res; + } +}; + +// 方法2:枚举 +class Solution { +public: + int minSwaps(vector& nums) { + int n = nums.size(); + int cnt = accumulate(nums.begin(), nums.end(), 0); + if(cnt == n || cnt == 0) return 0; + int cur = 0; + for(int i = 0;i < cnt;i++){ + cur += 1 - nums[i]; + } + int ans = cur; + for(int i = 1;i < n;i++){ + if(nums[i - 1] == 0) cur--; + if(nums[(i + cnt - 1) % n] == 0) cur++; + ans = min(ans, cur); + } + return ans; + } +}; diff --git "a/topic03/submit/LC53_\351\203\221\346\235\203\345\263\260.cpp" "b/topic03/submit/LC53_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..7402c13a32760d2f89ea77f495bc7ee523ba8899 --- /dev/null +++ "b/topic03/submit/LC53_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,42 @@ +#include +using namespace std; + +// 【题目】LC53.最大子数组和 +// 【难度】中等 +// 【提交】2025.9.27 https://leetcode.cn/problems/maximum-subarray/submissions/666395600 +// 【标签】数组、分治、动态规划 + +// 方法1: +class Solution { +public: + int maxSubArray(vector& nums) { + int n = nums.size(); + auto sums = vector(n+1, 0); + int min = 0; + int res = nums[0]; + bool falg = false; + for(int i = 1;i <= n;i++){ + sums[i] = sums[i-1] + nums[i-1]; + int x = sums[i-1]; + int y = sums[i]; + if(x < 0 && x < min) { + min = x; + } + res = max(res, y - min); + } + return res; + } +}; + +// 方法2: +class Solution { +public: + int maxSubArray(vector& nums) { + int pre = 0, res = nums[0]; + for(int num : nums){ + pre = max(pre + num, num); + res = max(res, pre); + } + return res; + } +}; diff --git "a/topic03/submit/LC918_\351\203\221\346\235\203\345\263\260.cpp" "b/topic03/submit/LC918_\351\203\221\346\235\203\345\263\260.cpp" new file mode 100644 index 0000000000000000000000000000000000000000..37b8f240e62b762b1314022d04369a7402380786 --- /dev/null +++ "b/topic03/submit/LC918_\351\203\221\346\235\203\345\263\260.cpp" @@ -0,0 +1,84 @@ +#include +using namespace std; + +// 【题目】LC918.环形子数组的最大和 +// 【难度】中等 +// 【提交】2025.9.27 https://leetcode.cn/problems/maximum-sum-circular-subarray/submissions/666415560 +// 【标签】队列、数组、分治、动态规划、单调队列、第105场周赛 + +// 方法1: +const auto _ = std::cin.tie(nullptr) -> sync_with_stdio(false); + +class Solution { +public: + int maxSubarraySumCircular(vector& nums) { + int n = nums.size(); + int pre = nums[0], maxAns = nums[0]; + for(int i = 1;i < n;i++){ + pre = max(pre + nums[i], nums[i]); + maxAns = max(maxAns, pre); + } + + vector preSums(n); + preSums[0] = nums[0]; + for(int i = 1;i < n;i++){ + preSums[i] = preSums[i-1] + nums[i]; + } + + vector left_Max(n+1, 0); + for(int i = 1;i <= n;i++){ + left_Max[i] = max(left_Max[i-1], preSums[i-1]); + } + for(int i = 1;i < n;i++){ + int sumRight = preSums[n-1] - preSums[i-1]; + maxAns = max(maxAns, sumRight + left_Max[i-1]); + } + return maxAns; + } +}; + +// 方法2:动态规划 +class Solution { +public: + int maxSubarraySumCircular(vector& nums) { + int n = nums.size(); + vector leftMax(n); + leftMax[0] = nums[0]; + int leftSum = nums[0]; + int pre = nums[0]; + int res = nums[0]; + for(int i = 1;i < n;i++){ + pre = max(pre + nums[i] ,nums[i]); + res = max(res, pre); + leftSum += nums[i]; + leftMax[i] = max(leftMax[i-1], leftSum); + } + + int rightSum = 0; + for(int i = n - 1;i > 0;i--){ + rightSum += nums[i]; + res = max(res, rightSum + leftMax[i - 1]); + } + return res; + } +}; + +// 方法3:取反 +class Solution { +public: + int maxSubarraySumCircular(vector& nums) { + int n = nums.size(); + int preMax = nums[0], maxRes = nums[0]; + int preMin = nums[0], minRes = nums[0]; + int sum = nums[0]; + for(int i = 1;i < n;i++){ + preMax = max(preMax + nums[i], nums[i]); + maxRes = max(maxRes,preMax); + preMin = min(preMin + nums[i], nums[i]); + minRes = min(minRes, preMin); + sum += nums[i]; + } + if(maxRes < 0) return maxRes; + else return max(maxRes, sum - minRes); + } +};