LeetCode-Solutions-in-Cpp17

Solutions to high-frequency interview questions of LeetCode in C++17, taking into account both efficiency and comprehensibility.


Project maintained by downdemo Hosted on GitHub Pages — Theme by mattgraham
class Solution {
 public:
  vector<int> searchRange(vector<int>& nums, int target) {
    if (!binary_search(begin(nums), end(nums), target)) {
      return {-1, -1};
    }
    int l = lower_bound(begin(nums), end(nums), target) - begin(nums);
    int r = upper_bound(begin(nums), end(nums), target) - begin(nums) - 1;
    return {l, r};
  }
};
int binarySearch(vector<int>& nums, int target) {
  int l = 0;
  int r = size(nums);  // 右边界为最后一个元素的后一位置
  while (l != r) {  // 只要左右区间不重合,就说明范围中有元素
    int m = l + (r - l) / 2;  // 防溢出所以不写 (l + r) / 2
    if (nums[m] == target) {
      return m;  // 找到则返回
    } else if (nums[m] > target) {
      r = m;  // 下一范围右边界不包含 m
    } else {
      l = m + 1;  // 下一范围左边界不包含 m
    }
  }           // 结束时 l == r,[l, r) 内不包含任何元素
  return -1;  // 未找到返回 -1
}
int binarySearch(vector<int>& nums, int target) {
  int l = 0;
  int r = size(nums) - 1;  // 右边界为最后一个元素
  while (l <= r) {         // 包含右边界,所以应该有等号
    int m = l + (r - l) / 2;
    if (nums[m] == target) {
      return m;
    } else if (nums[m] > target) {
      r = m - 1;
    } else {
      l = m + 1;
    }
  }
  return -1;
}
int lowerBound(vector<int>& nums, int target) {
  int l = 0;
  int r = size(nums);
  while (l != r) {
    int m = l + (r - l) / 2;
    if (nums[m] >= target) {
      r = m;  // 满足条件则继续左压
    } else {
      l = m + 1;
    }
  }  // r 是满足条件的右边界,最后一次左压结束时 r 恰好是第一个满足条件的位置
  // 比如数组只有一个元素且满足条件,则左压一次 l 和 r 都为 0
  // r 恰好落在第一个满足条件的位置
  // 结束时l == r,下面用到的 l 都可以换成 r
  if (l == size(nums)) {  // 没有左压过
    return -1;            // 不会有满足条件的值
  }
  return l;
}
template <typename F>
int binarySearch(vector<int>& nums, int n, F check) {
  int l = 0;
  int r = size(nums);
  while (l != r) {
    int m = l + (r - l) / 2;
    if (check(nums[m])) {  // 满足条件则继续左压
      r = m;
    } else {  // 不满足条件则右压
      l = m + 1;
    }
  }
  if (l == size(nums)) {  // 没有左压过
    return -1;            // 不会有满足条件的值
  }
  return l;
}
int upperBound(vector<int>& nums, int target) {
  int l = 0;
  int r = size(nums);
  while (l < r) {
    int m = l + (r - l) / 2;
    if (nums[m] > target) {
      r = m;
    } else {
      l = m + 1;
    }
  }
  if (l == size(nums)) {
    return -1;
  }
  return l;
}
class Solution {
 public:
  vector<int> searchRange(vector<int>& nums, int target) {
    int a = lowerBound(nums, 0, size(nums), target);
    int b = upperBound(nums, 0, size(nums), target);
    return {a, b};
  }

  int lowerBound(vector<int>& nums, int l, int r, int target) {
    while (l != r) {
      int m = l + (r - l) / 2;
      if (nums[m] >= target) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    return l < size(nums) && nums[l] == target ? l : -1;
  }

  int upperBound(vector<int>& nums, int l, int r, int target) {
    while (l != r) {
      int m = l + (r - l) / 2;
      if (nums[m] > target) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    return l > 0 && nums[l - 1] == target ? l - 1 : -1;
  }
};