찾기---2분 찾기의 세 가지 실현과 삽입값 찾기
24524 단어 데이터 구조와 알고리즘
이분 찾기
public class BinarySearchTest {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
int index1 = binarySearch1(arr, 5);
System.out.println(index1);
int index2 = binarySearch2(arr, 5);
System.out.println(index2);
int index3 = binarySearchRecursion(arr, 5);
System.out.println(index3);
}
//
public static int binarySearchRecursion(int[] arr, int target) {
return binarySearch3(arr, 0, arr.length - 1, target);
}
public static int binarySearch3(int[] arr, int left, int right, int target) {
if(left > right) return -1;
int mid = left + (right - left) / 2;
if(arr[mid] > target) {
return binarySearch3(arr, left, mid - 1, target);
}else if(arr[mid] < target) {
return binarySearch3(arr, mid + 1, right, target);
}else {
return mid;
}
}
// :
public static int binarySearch1(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if(arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
}else{
right = mid - 1;
}
}
return -1;
}
// :
public static int binarySearch2(int[] arr, int target) {
int left = 0;
int right = arr.length;
while(left < right) {
int mid = left + (right - left) / 2;
if(target < arr[mid]) {
right = mid;
}else if(target > arr[mid]) {
left = mid + 1;
}else{
return mid;
}
}
return -1;
}
}
확장 문제
그룹에 같은 목표 값이 여러 개 있습니다. 이 값의 아래 표시를 찾아내십시오. 예를 들어 {1,2,2,3,4} 목표 값이 2이면 {1,2}로 돌아갑니다.
import java.util.ArrayList;
import java.util.List;
public class BinarySearchExtension {
public static void main(String[] args) {
int[] arr = {1,2,2,3,4,4,4};
List<Integer> result = binarySearchRecursion(arr, 3);
System.out.println(result);
}
public static List binarySearchRecursion(int[] arr, int target) {
return binarySearch1(arr, 0, arr.length - 1, target);
}
public static List binarySearch1(int[] arr, int left, int right, int target) {
if(left > right) {
return new ArrayList<>();
}
int mid = left + (right - left) / 2;
if(arr[mid] > target) {
return binarySearch1(arr, left, mid - 1, target);
}else if(arr[mid] < target) {
return binarySearch1(arr, mid + 1, right, target);
}else{
int temp1 = mid - 1;
int temp2 = mid + 1;
int arrLen = arr.length;
List<Integer> result = new ArrayList<>();
// mid
while(temp1 >= 0 && arr[temp1] == target) {
result.add(temp1);
temp1--;
}
result.add(mid);
// mid
while(temp2 < arrLen && arr[temp2] == target) {
result.add(temp2);
temp2++;
}
return result;
}
}
}
시간 복잡도
매번 찾을 때마다 원소의 개수를 반으로 줄인다. 즉, n, n/2, n/4,..., n/2^k, k는 순환하는 횟수이다. n/2^k=1, 즉 k=logn(2를 밑으로), 따라서 시간의 복잡도는 O(logN)이다.
보간 찾기
2분 찾기에서 중간 원소
mid= left + (right - left)/ 2
를 추출하고 이런 예를 생각해 보자. 데이터는 1부터 1000까지이고 원소1을 찾으면 몇 번의 순환을 거쳐야 1을 찾을 수 있다.그래서 개선된 알고리즘은 바로 삽입 알고리즘이다. mid=left + (right - left) * (target -arr[left]) / (arr[right] - arr[left])
, target은 목표 값을 찾아야 한다.데이터의 양이 비교적 크고 키워드의 분포가 비교적 균일한 검색에 있어 삽입값으로 찾는 속도가 비교적 빠르다.키워드의 분포가 고르지 않은 상황에서 이 방법이 반드시 2점보다 검색 효율이 높은 것은 아니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
두 갈래 나무의 깊이가 두루 다니다텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.