真正写对「二分查找」,从来不在于我们把区间写成了「左闭右开」还是「左闭右闭」,而是 在于我们能够根据题意:得到某种单调性,和可以逐步缩小搜索规模的条件,进而准确地设计可以使得搜索区间缩小的条件。
565. 数组嵌套
代码实现(首刷自解)
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int n = 0, maxNum = -1;
int num;
set<int> s;
for (const auto& nu : nums) {
n = 0;
num = nu;
while (!s.count(nums[num])) {
s.emplace(nums[num]);
num = nums[num];
n++;
}
maxNum = max(maxNum, n);
}
return maxNum;
}
};
222. 完全二叉树的节点个数
代码实现(首刷自解)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int countNodes(TreeNode* root) {
if (!root) return 0;
int level = 0;
TreeNode* tmp = root;
while (tmp) {
tmp = tmp->left;
level++;
}
int num = 0;
while (level >= 0) {
if (!root->right) break;
root = root->right;
num += (pow(2, level - 2), 1);
level--;
}
return num;
}
};
1712. 将数组分成三个子数组的方案数
代码实现(首刷自解)
class Solution {
public:
int waysToSplit(vector<int>& nums) {
long long ans = 0;
int n = nums.size();
for (int i = 1; i < n; i++) {
nums[i] += nums[i - 1];
}
for (int i = 0; i < n - 2; i++) {
int lower = 2 * nums[i];
int higher = (nums.back() + nums[i]) / 2;
auto left = lower_bound(nums.begin() + i + 1, nums.end() - 1, lower);
auto right = upper_bound(nums.begin() + i + 1, nums.end() - 1, higher);
int tmp = right - left;
if (tmp < 0) break;
ans += tmp;
}
return ans % 1000000007;
}
};