알고리즘

이진탐색을 활용하는 여러가지 경우 구현

웅둘 2024. 1. 19. 11:18

이진 탐색

이진탐색이란 중복 값이 없는 정렬된 배열에서 원하는 값을 찾는 효율적인 알고리즘이다.

 

핵심 로직

  1. 배열의 중앙값을 구한다.
  2. 중앙값과 찾고자 하는 값(target)과 비교한다.
    1. 중앙값 < target 인 경우 : 시작점을 중앙값의 +1 값으로 선택 ( 중앙 기준 왼쪽을 버린다.)
    2. 중앙값 > target 인 경우 : 끝점을 중앙값의 -1 값으로 선택 (중앙 기준 오른쪽을 버린다.)

 

배열에 있는 값의 인덱스 찾기

public static int search(int[] temp, int target) {
  int start = 0;
  int end = temp.length - 1;
  int result = -1;

  while(start <= end) {
      int mid = (start + end) / 2;
      if (temp[mid] < target) {
          start = mid + 1;
      } else if (temp[mid] > target){
          end = mid - 1;
      } else {
          return mid;
      }
  }

  return result;
}

 

target 보다 크거나 같은 인덱스 찾기

public static int searchGreaterOrEqualIndex(int[] temp, int target) {
    int start = 0;
    int end = temp.length - 1;

    while(start <= end) {
        int mid = (start + end) / 2;
        if (temp[mid] < target) {
            start = mid + 1;
        } else if (temp[mid] > target){
            end = mid - 1;
        } else {
            return mid;
        }
    }

    return start;
}

 

target 보다 작거나 같은 인덱스 찾기

public static int searchSmallerOrEqualIndex(int[] temp, int target) {
    int start = 0;
    int end = temp.length - 1;

    while(start <= end) {
        int mid = (start + end) / 2;
        if (temp[mid] < target) {
            start = mid + 1;
        } else if (temp[mid] > target){
            end = mid - 1;
        } else {
            return mid;
        }
    }

    return end;
}

 

중복이 있는 배열에서 target과 같은 첫 번째 인덱스 찾기

public static int searchDuplicateFirstIndex(int[] temp, int target) {
    int start = 0;
    int end = temp.length - 1;
    int result = -1;

    while(start <= end) {
        int mid = (start + end) / 2;
        if (temp[mid] < target) {
            start = mid + 1;
        } else {
            result = mid;
            end = mid - 1;
        }
      }
return result;
}

 

중복이 있는 배열에서 target과 같은 마지막 인덱스 찾기

public static int searchDuplicateLastIndex(int[] temp, int target) {
		int start = 0;
		int end = temp.length - 1;
		int result = -1;
		
		while(start <= end) {
		    int mid = (start + end) / 2;
		    if(temp[mid] <= target) {
		        start = mid + 1;
		    } else {
		        result = mid;
		        end = mid - 1;
		    }
		}
		return result-1;
}

 

전체 코드

public class binarySearch {

    public static void main(String[] args) {
        int[] array = {1, 2, 4, 6, 9, 13};
        System.out.println(search(array, 4));           // 2
        System.out.println(searchGreaterOrEqualIndex(array, 7)); // 4
        System.out.println(searchSmallerOrEqualIndex(array, 7));  // 3

        int[] duplicateArray = {1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5};
        System.out.println(searchDuplicateFirstIndex(duplicateArray, 3));  // 5
        System.out.println(searchDuplicateLastIndex(duplicateArray, 3));   // 7
    }

    public static int search(int[] temp, int target) {
        int start = 0;
        int end = temp.length - 1;
        int result = -1;

        while(start <= end) {
            int mid = (start + end) / 2;
            if (temp[mid] < target) {
                start = mid + 1;
            } else if (temp[mid] > target){
                end = mid - 1;
            } else {
                return mid;
            }
        }

        return result;
    }

    public static int searchGreaterOrEqualIndex(int[] temp, int target) {
        int start = 0;
        int end = temp.length - 1;

        while(start <= end) {
            int mid = (start + end) / 2;
            if (temp[mid] < target) {
                start = mid + 1;
            } else if (temp[mid] > target){
                end = mid - 1;
            } else {
                return mid;
            }
        }

        return start;
    }

    public static int searchSmallerOrEqualIndex(int[] temp, int target) {
        int start = 0;
        int end = temp.length - 1;

        while(start <= end) {
            int mid = (start + end) / 2;
            if (temp[mid] < target) {
                start = mid + 1;
            } else if (temp[mid] > target){
                end = mid - 1;
            } else {
                return mid;
            }
        }

        return end;
    }
    public static int searchDuplicateFirstIndex(int[] temp, int target) {
        int start = 0;
        int end = temp.length - 1;
        int result = -1;

        while(start <= end) {
            int mid = (start + end) / 2;
            if (temp[mid] < target) {
                start = mid + 1;
            } else {
                result = mid;
                end = mid - 1;
            }
        }
        return result;
    }

    public static int searchDuplicateLastIndex(int[] temp, int target) {
        int start = 0;
        int end = temp.length - 1;
        int result = -1;

        while(start <= end) {
            int mid = (start + end) / 2;
            if(temp[mid] <= target) {
                start = mid + 1;
            } else {
                result = mid;
                end = mid - 1;
            }
        }
        return result-1;
    }
}