二分(折半)查找算法O(logN):
作用:查找某个元素是否存在,无论有几个,只要有就行。
首先单调性:否则需要自己排序
需要3个指针,min头指针、max尾指针、min指针 = (min + max) / 2
调整:
if (arr[mid] < x) min = mid + 1;
if (arr[mid] > x) max = mid - 1;
if (arr[mid] == x) return FIND;
if (min > max) break;
int binary_search(int* arr, int x, int n) {
int min = 0, max = n - 1, mid;
while (min <= max) {
mid = (min + max) / 2;
if (arr[mid] == x)
return mid;
if (arr[mid] < x)
min = mid + 1;
else
max = mid - 1;
}
return -1;
}
其中, / 2可优化为 >> 1
改递归:
①边界条件: min > max 或 arr[mid] == x
②更新min,max,然后甩锅给下次递归处理。
// 头递归(递推),需要回溯
int binary_search(int* arr, int min, int max, int x) {
if (min > max) return -1;
int mid = (min + max) >> 1;
if (arr[mid] == x) return mid;
if (arr[mid] < x) min = mid + 1;
else max = mid - 1;
return binary_search(arr, min, max, x);
}
尾递归是从尾部直接算到头部。
任何的编程问题都能用递归实现。
PS:快速排序不稳定O(NlogN),容易退化成O(N^2).
===========================
// 二分查找
#include <iostream>
#include <ctime>
using namespace std;
int binary_search(int* arr, int min, int max, int x) {
if (min > max) return -1;
int mid = (min + max) >> 1;
if (arr[mid] == x) return mid;
else if (arr[mid] < x) min = mid + 1;
else max = mid - 1;
return binary_search(arr, min, max, x);
}
// int min = 0, max = n - 1, mid;
// while (min <= max) {
// mid = (min + max) / 2;
// if (arr[mid] < x) min = mid + 1;
// else if (arr[mid] > x) max = mid - 1;
// else return mid;
// return -1;
// }
int main() {
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8 , 9, 10};
srand(time(0));
int x = rand() % 12;
if (binary_search(arr, 0, 9, x) != -1)
cout << "Num:" << binary_search(arr, 0, 9, x) << "is x value" << endl;
else
cout << "NO" <<endl;
return 0;
}
-----------------------------------------------
OJ刷题:165(船长没做出来)
枚举素勾股数
3、 4 、5 素勾股数,三个数之间相互 互素,通过3个素勾股数可以推出其他的勾股数,
m>n ,m与n互素
a^2 + b^2 = c^2
a = m^2 - n ^2
b = 2mn
c = m^2 + n^2