当前位置:   article > 正文

【数据结构】数组复习-二分查找法

【数据结构】数组复习-二分查找法

写这篇博客的起因:

刚开始刷力扣,发现没有一个很好的做题方法,在网络上发现了这个博主的评论,如下。感觉挺适合我,所以开始复习一下数据结构。

c++基础主要是看:

刷题主要是看:

  • 3.leetcode-labuladong系列

《labuladong 的算法笔记》纸质书 | labuladong 的算法笔记

一、数组-二分法

问题1:左闭右闭,左闭右开,左开右闭

一般使用左闭右闭和左闭右开比较多

1:左闭右开(left<right)

  1. left=0
  2. right=len(num)-1
  3. m1 = (right - left) // 2 + left
  4. while(left<right):
  5. m1>t,right=m1
  6. m1<t,left=m1+1
  7. m1=t,m1

2:左闭右闭(left<=right)

  1. left=0
  2. right=len(num)-1
  3. m1 = (right - left) // 2 + left
  4. while(left<=right):
  5. m1>t,right=m1-1
  6. m1<t,left=m1+1
  7. m1=t,m1

二、力扣相关例题

704题:二分查找

python语言-左闭右开

  1. from typing import List
  2. class Solution:
  3. def search(self, nums: List[int], target: int) -> int:
  4. # self: 这是一个特殊的参数,用来引用类的实例本身。在类方法中,self 是必须的,但在调用方法时通常不需要显式传入,Python会自动处理。
  5. # nums: List[int]: 这是函数的第一个参数,命名为 nums,类型注解指示它应该是一个整数列表。
  6. # target: int: 这是函数的第二个参数,命名为 target,类型注解指示它应该是一个整数。
  7. # -> int: 这部分指定了函数的返回类型,即该函数会返回一个整数。
  8. left, right = 0, len(nums)
  9. while left < right:
  10. middle = left + (right - left) // 2
  11. if nums[middle] > target:
  12. right = middle
  13. elif nums[middle] < target:
  14. left = middle + 1
  15. else:
  16. return middle
  17. return -1
  18. def main():
  19. # Example usage:
  20. nums = [-1, 0, 3, 5, 9, 12]
  21. target = 9
  22. solution = Solution()
  23. result = solution.search(nums, target)
  24. print(f"Index of {target} in {nums}: {result}")
  25. if __name__ == "__main__":
  26. main()

python语言-左闭右闭

  1. from typing import List
  2. class Solution:
  3. def search(self, nums: List[int], target: int) -> int:
  4. # self: 这是一个特殊的参数,用来引用类的实例本身。在类方法中,self 是必须的,但在调用方法时通常不需要显式传入,Python会自动处理。
  5. # nums: List[int]: 这是函数的第一个参数,命名为 nums,类型注解指示它应该是一个整数列表。
  6. # target: int: 这是函数的第二个参数,命名为 target,类型注解指示它应该是一个整数。
  7. # -> int: 这部分指定了函数的返回类型,即该函数会返回一个整数。
  8. left, right = 0, len(nums) - 1 # 定义target在左闭右闭的区间里,[left, right]
  9. while left <= right:
  10. middle = left + (right - left) // 2
  11. if nums[middle] > target:
  12. right = middle - 1 # target在左区间,所以[left, middle - 1]
  13. elif nums[middle] < target:
  14. left = middle + 1 # target在右区间,所以[middle + 1, right]
  15. else:
  16. return middle # 数组中找到目标值,直接返回下标
  17. return -1 # 未找到目标值
  18. def main():
  19. # Example usage:
  20. nums = [-1, 0, 3, 5, 9, 12]
  21. target = 9
  22. solution = Solution()
  23. result = solution.search(nums, target)
  24. print(f"Index of {target} in {nums}: {result}")
  25. if __name__ == "__main__":
  26. main()

c++语言-左闭右开

  1. # include <vector>
  2. class Solution {
  3. public:
  4. int search(std::vector<int>& nums, int target) {
  5. int left = 0;
  6. int right = nums.size(); // right is the index just beyond the end of the vector
  7. while (left < right) {
  8. int middle = left + (right - left) / 2;
  9. if (nums[middle] > target) {
  10. right = middle; // target in left half, [left, middle)
  11. } else if (nums[middle] < target) {
  12. left = middle + 1; // target in right half, [middle + 1, right)
  13. } else {
  14. return middle; // target found at index middle
  15. }
  16. }
  17. return -1; // target not found
  18. }
  19. };
  20. // Example usage
  21. #include <iostream>
  22. int main() {
  23. Solution solution;
  24. std::vector<int> nums = {-1, 0, 3, 5, 9, 12};
  25. int target = 9;
  26. int result = solution.search(nums, target);
  27. std::cout << "Index of " << target << " in nums: " << result << std::endl;
  28. return 0;
  29. }

c++语言-左闭右闭

  1. # include <vector>
  2. class Solution {
  3. public:
  4. int search(std::vector<int>& nums, int target) {
  5. int left = 0;
  6. int right = nums.size(); // right is the index just beyond the end of the vector
  7. while (left <= right) {
  8. int middle = left + (right - left) / 2;
  9. if (nums[middle] > target) {
  10. right = middle-1; // target in left half, [left, middle)
  11. } else if (nums[middle] < target) {
  12. left = middle + 1; // target in right half, [middle + 1, right)
  13. } else {
  14. return middle; // target found at index middle
  15. }
  16. }
  17. return -1; // target not found
  18. }
  19. };
  20. // Example usage
  21. #include <iostream>
  22. int main() {
  23. Solution solution;
  24. std::vector<int> nums = {-1, 0, 3, 5, 9, 12};
  25. int target = 9;
  26. int result = solution.search(nums, target);
  27. std::cout << "Index of " << target << " in nums: " << result << std::endl;
  28. return 0;
  29. }

相关题目:

35题:搜索插入位置

  1. #
  2. # @lc app=leetcode.cn id=35 lang=python
  3. #
  4. # [35] 搜索插入位置
  5. #
  6. # @lc code=start
  7. from typing import List
  8. class Solution():
  9. def searchInsert(self, nums: List[int], target: int) -> int:
  10. """
  11. :type nums: List[int]
  12. :type target: int
  13. :rtype: int
  14. """
  15. left = 0
  16. right = len(nums) # 左闭右开区间 [left, right)
  17. while left < right: # 区间不为空
  18. # 循环不变量:
  19. # nums[left-1] < target
  20. # nums[right] >= target
  21. mid = left + (right - left) // 2
  22. if nums[mid] < target:
  23. left = mid + 1 # 范围缩小到 [mid+1, right)
  24. else:
  25. right = mid # 范围缩小到 [left, mid)
  26. return left # 或者 right
  27. def main():
  28. nums = [-1, 0, 3, 5, 9, 12]
  29. target = 8
  30. solution = Solution()
  31. result = solution.searchInsert(nums, target)
  32. print(f"Index of {target} in {nums}: {result}")
  33. if __name__ == "__main__":
  34. main()
  35. # @lc code=end


34题:在排序数组中查找元素的第一个和最后一个位置

  1. #
  2. # @lc app=leetcode.cn id=34 lang=python
  3. #
  4. # [34] 在排序数组中查找元素的第一个和最后一个位置
  5. #
  6. # @lc code=start
  7. from typing import List
  8. class Solution:
  9. def searchRange(self, nums: List[int], target: int) -> List[int]:
  10. left = 0
  11. right = len(nums) - 1
  12. result = [-1, -1]
  13. # Edge case: empty list
  14. if not nums:
  15. return result
  16. # Binary search for the left boundary of target
  17. while left <= right:
  18. middle = left + (right - left) // 2
  19. if nums[middle] < target:
  20. left = middle + 1
  21. else:
  22. right = middle - 1
  23. # After the loop, `left` is the index of the first occurrence of `target`
  24. if left < len(nums) and nums[left] == target:
  25. result[0] = left
  26. else:
  27. return result
  28. # Binary search for the right boundary of target
  29. left = 0
  30. right = len(nums) - 1
  31. while left <= right:
  32. middle = left + (right - left) // 2
  33. if nums[middle] <= target:
  34. left = middle + 1
  35. else:
  36. right = middle - 1
  37. # After the loop, `right` is the index of the last occurrence of `target`
  38. result[1] = right
  39. return result
  40. def main():
  41. nums = [-1, 0, 3, 5, 9, 9, 12]
  42. target = 10
  43. solution = Solution()
  44. result = solution.searchRange(nums, target)
  45. print(f"Indices of {target} in {nums}: {result}")
  46. if __name__ == "__main__":
  47. main()
  1. c++
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. class Solution {
  6. public:
  7. vector<int> searchRange(vector<int>& nums, int target) {
  8. vector<int> result = {-1, -1};
  9. int left = 0;
  10. int right = nums.size() - 1;
  11. // First binary search to find the leftmost index of target
  12. while (left <= right) {
  13. int mid = left + (right - left) / 2;
  14. if (nums[mid] < target) {
  15. left = mid + 1;
  16. } else if (nums[mid] > target) {
  17. right = mid - 1;
  18. } else {
  19. // Found target, adjust right to search left part
  20. result[0] = mid;
  21. right = mid - 1;
  22. }
  23. }
  24. // Second binary search to find the rightmost index of target
  25. left = 0;
  26. right = nums.size() - 1;
  27. while (left <= right) {
  28. int mid = left + (right - left) / 2;
  29. if (nums[mid] < target) {
  30. left = mid + 1;
  31. } else if (nums[mid] > target) {
  32. right = mid - 1;
  33. } else {
  34. // Found target, adjust left to search right part
  35. result[1] = mid;
  36. left = mid + 1;
  37. }
  38. }
  39. return result;
  40. }
  41. };
  42. int main() {
  43. vector<int> nums = {-1, 0, 3, 5, 9, 9, 9, 12};
  44. int target = 9;
  45. Solution solution;
  46. vector<int> result = solution.searchRange(nums, target);
  47. cout << "Indices of " << target << " in nums: [" << result[0] << ", " << result[1] << "]" << endl;
  48. return 0;
  49. }

367题:有效的完全平方数

  1. #include <iostream>
  2. using namespace std;
  3. bool isPerfectSquare(int num) {
  4. if (num == 0 || num == 1) {
  5. return true;
  6. }
  7. long left = 1;
  8. long right = num;
  9. long mid = 0;
  10. while (left <= right) {
  11. mid = (left + right + 1) / 2; // 保证处理到右边界
  12. long long res = mid * mid; // 使用 long long 来存放结果,避免整数溢出
  13. if (res == num) {
  14. return true;
  15. } else if (res > num) {
  16. // [left, mid-1] 区间继续找
  17. right = mid - 1;
  18. } else {
  19. // [mid+1, right] 区间继续找
  20. left = mid + 1;
  21. }
  22. }
  23. return false;
  24. }
  25. int main() {
  26. // 测试数据
  27. int nums[] = {16, 14, 25, 0, 1, 100, 99};
  28. int n = sizeof(nums) / sizeof(nums[0]);
  29. for (int i = 0; i < n; ++i) {
  30. cout << "Number " << nums[i] << (isPerfectSquare(nums[i]) ? " is" : " is not") << " a perfect square." << endl;
  31. }
  32. return 0;
  33. }
  1. #include <iostream>
  2. using namespace std;
  3. bool isPerfectSquare(int num) {
  4. if (num == 0 || num == 1) {
  5. return true;
  6. }
  7. long left = 1;
  8. long right = num;
  9. long mid = 0;
  10. while (left <= right) {
  11. mid = (left + right + 1) / 2; // 保证处理到右边界
  12. long long res = mid * mid; // 使用 long long 来存放结果,避免整数溢出
  13. if (res == num) {
  14. return true;
  15. } else if (res > num) {
  16. // [left, mid-1] 区间继续找
  17. right = mid - 1;
  18. } else {
  19. // [mid+1, right] 区间继续找
  20. left = mid + 1;
  21. }
  22. }
  23. return false;
  24. }
  25. int main() {
  26. // 测试数据
  27. int nums[] = {16, 14, 25, 0, 1, 100, 99};
  28. int n = sizeof(nums) / sizeof(nums[0]);
  29. for (int i = 0; i < n; ++i) {
  30. cout << "Number " << nums[i] << (isPerfectSquare(nums[i]) ? " is" : " is not") << " a perfect square." << endl;
  31. }
  32. return 0;
  33. }

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/952595
推荐阅读
相关标签
  

闽ICP备14008679号