1.1 배열 - 이진 검색(Leetcode 0704)

1. 주제

Leetcode 링크
n개의 요소와 대상 값 target이 있는 정렬된(오름차순) 정수 배열 nums가 주어지면 nums에서 대상을 검색하는 함수를 작성하고 대상 값이 존재하면 아래 첨자를 반환하고 그렇지 않으면 -1을 반환합니다.

입력: nums = [-1,0,3,5,9,12], target = 9
출력: 4
설명: 9는 첨자 4와 함께 nums에 나타납니다.

입력: nums = [-1,0,3,5,9,12], target = 2
출력: -1
설명: nums에는 2가 없으므로 -1을 반환합니다.

2. 아이디어

이분법 사용의 전제 : 정렬된 배열 + 배열에 중복 요소 없음

일반적으로 이분 간격의 두 가지 정의가 있습니다 . 왼쪽이 닫히고 오른쪽이 닫힘[왼쪽, 오른쪽] 또는 왼쪽이 닫히고 오른쪽이 열림[왼쪽, 오른쪽]

3. 코드 구현

3.1 쓰기 방법 1: 왼쪽 닫힘 및 오른쪽 닫힘


class Solution {
    
    
public:
    int search(vector<int>& nums, int target) {
    
    
        // 定义初始左闭右闭区间[left, right]
    	int left = 0;
    	int right = nums.size() - 1;
		// 进行区间遍历,注意左闭右闭的区间对应的是<=
		while(left <= right){
    
    
			// middle的防止溢出写法,等同于(right+left) / 2
			int middle = left + (right - left) / 2;

            // 分成三种情况
			if (nums[middle] > target){
    
    
                right = middle - 1; // 新的区间落入原来的左半区间
            }
            else if (nums[middle] < target){
    
    
                left = middle + 1; // 新的区间落入原来的右半区间
            }
            else{
    
    
                return middle; // nums[middle] == target
            }
        }
        return -1; // 未找到目标值

    }
};

3.2 쓰기 방법 2: 왼쪽 닫힘 및 오른쪽 열림

class Solution {
    
    
public:
    int search(vector<int>& nums, int target) {
    
    
        // 定义初始左闭右开区间[left, righ)
    	int left = 0;
    	int right = nums.size() ;
		// 进行区间遍历,注意左闭右开的区间对应的是<,因为取不到“right”对应位置的元素
		while(left < right){
    
    
			// middle的防止溢出写法,等同于(right+left) / 2
			int middle = left + (right - left) / 2;

            // 分成三种情况,注意要带着左闭右开的区间思想[left, right)
			if (nums[middle] > target){
    
    
                right = middle ; // 新的区间落入原来的左半区间, 右开, [left, middle)
            }
            else if (nums[middle] < target){
    
    
                left = middle + 1; // 新的区间落入原来的右半区间, 左闭, [middle + 1, right)
            }
            else{
    
    
                return middle; // nums[middle] == target
            }
        }
        return -1; // 未找到目标值

    }
};

4. 요약

4.1 오버플로 방지 쓰기 방법

// middle的防止溢出写法,等同于(right+left) / 2
int middle = left + (right - left) / 2;

4.2 배열 길이의 패리티

  • 배열이 홀수인지 짝수인지에 관계없이 전체 배열은 배열의 길이에 따라 순회됩니다.
  • 배열 길이 패리티의 영향은 중간 위치 값에 반영, (오른쪽+왼쪽) / 2
4.3 이분법의 핵심: 구간 정의 파악
  • 검색 구간의 정의에 따라 경계 처리를 합니다.
  • 구간의 정의는 불변이므로 루프 내에서 검색 구간의 정의에 따라 경계처리를 하도록 주장하는 것이 루프 불변의 법칙이다.

추천

출처blog.csdn.net/weixin_46297585/article/details/122572956