最近每天晚上和室友做力扣 ,白天整理下。
16. 最接近的三数之和
这里室友想到的解法是贪心,不断缩小,但最终我们判断这种方法不可行。我想到的解法是先排序,对有序数组的前两个数都是遍历找到的,第三个数通过二分找,这样时间复杂度是O(n²logn),也没有缩小很多。。。
最后,我们看了答案。
从答案中有两点可以学习到。一是记得调用abs数学函数,另外要记得在有序数组中找两个数相加和目标值最接近的寻找方法是O(n)复杂度,即题解的做法。
下面是官方题解:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int n = nums.size();
int best = 1e7;
// 根据差值的绝对值来更新答案
auto update = [&](int cur) {
if (abs(cur - target) < abs(best - target)) {
best = cur;
}
};
// 枚举 a
for (int i = 0; i < n; ++i) {
// 保证和上一次枚举的元素不相等
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
// 使用双指针枚举 b 和 c
int j = i + 1, k = n - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
// 如果和为 target 直接返回答案
if (sum == target) {
return target;
}
update(sum);
if (sum > target) {
// 如果和大于 target,移动 c 对应的指针
int k0 = k - 1;
// 移动到下一个不相等的元素
while (j < k0 && nums[k0] == nums[k]) {
--k0;
}
k = k0;
} else {
// 如果和小于 target,移动 b 对应的指针
int j0 = j + 1;
// 移动到下一个不相等的元素
while (j0 < k && nums[j0] == nums[j]) {
++j0;
}
j = j0;
}
}
}
return best;
}
};
来源:力扣
- 将数组拆分成斐波那契序列
这个虽然题解和我想的暴力解法一样,但是递归代码优美了很多,学习到了,写代码要简洁优美。要注意的是这里用的是long long
class Solution {
public:
vector<int> splitIntoFibonacci(string S) {
vector<int> list;
backtrack(list, S, S.length(), 0, 0, 0);
return list;
}
bool backtrack(vector<int>& list, string S, int length, int index, long long sum, int prev) {
if (index == length) {
return list.size() >= 3;
}
long long curr = 0;
for (int i = index; i < length; i++) {
if (i > index && S[index] == '0') {
break;
}
curr = curr * 10 + S[i] - '0';
if (curr > INT_MAX) {
break;
}
if (list.size() >= 2) {
if (curr < sum) {
continue;
}
else if (curr > sum) {
break;
}
}
list.push_back(curr);
if (backtrack(list, S, length, i + 1, prev + curr, curr)) {
return true;
}
list.pop_back();
}
return false;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence/solution/jiang-shu-zu-chai-fen-cheng-fei-bo-na-qi-ts6c/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。