注意区间的开闭,影响运行结果。
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size();
while (left < right) { // 左闭右开
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
} else {
return mid;
}
}
return -1;
}
};
若不存在,最后返回left即可
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0, right = nums.size();
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
} else {
return mid;
}
}
return left;
}
};
LeetCode 34 在排序数组中查找元素的第一个和最后一个位置
先用二分找到对应元素,再往左右寻找边界。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left = 0, right = nums.size();
int mid = 0;
while (left < right) {
mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
} else {
left = mid; right = mid;
while (left >= 0 && nums[left] == target) {
--left;
}
while (right < nums.size() && nums[right] == target) {
++right;
}
return {left + 1, right - 1};
}
}
return {-1, -1};
}
};
优化的双指针,减少元素的移动
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left = 0, right = nums.size();
while (left < right) {
if (nums[left] == val) {
nums[left] = nums[right - 1];
right--;
} else {
left++;
}
}
return left;
}
};
每日一题,记录每个结点的边的个数(度),取最大的两个结点即为答案。若两点间有连接,则再减1。
class Solution {
public:
int maximalNetworkRank(int n, vector<vector<int>>& roads) {
vector<int> cnt(n, 0);
vector<vector<int>> g(n, vector<int>(n ,0));
for (auto& r : roads) {
int a = r[0], b = r[1];
g[a][b] = g[b][a] = 1;
++cnt[a];
++cnt[b];
}
int ans = 0;
for (int a = 0; a < n; ++a) {
for (int b = a + 1; b < n; ++b) {
ans = max(ans, cnt[a] + cnt[b] - g[a][b]);
}
}
return ans;
}
};