数组问题在面试中很常见:
排序:选择排序;插入排序;归并排序;快速排序
查找:二分查找
数据结构:栈;队列;堆
如何写出正确的程序
- 明确变量的含义
- 循环不变量
- 小数据调试(边界,特例)
- 大数据量测试
二分查找法:边界处理
循环不变量:在循环中,声明的区间不变。控制区间边界,保证其含义不变
二分查找1:循环不变量为[l…r]的范围内寻找target
template<typename T>
int binarySearch(T arr[], int n, T target){
int l = 0, r = n -1; //[l....r]的范围内寻找target
while (l <= r) { //当 l== r时, 区间[l....r]依旧有效、
int mid = l + (r - l) / 2;
if (arr[mid] == target)
return mid;
if (target > arr[mid])
l = mid + 1; //target在[mid+1...r]中
else{
r = mid - 1; //target在[l...mid-1]中
}
}
return -1;
}
生成长度为n的有序数组
int *generateRandomArray(int n){
assert(n > 0);
int *arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = i;
return arr;
}
main函数
int main() {
int n = 10000000;
int *data = myUntil::generateRandomArray(n);
clock_t startTime = clock();
for (int i = 0; i < n; i++){
assert(i == binarySearch(data, n, i));
}
clock_t endTime = clock();
cout << "binarySearch test complete." << endl;
cout << "Time Cost: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
system("pause");
return 0;
}
二分查找2:循环不变量为[l…r)的范围内寻找target
template<typename T>
int binarySearch2(T arr[], int n, T target){
int l = 0, r = n ; //[l....r)的范围内寻找target
while (l < r) { //当 l== r时, 区间[l....r)依旧有效、
int mid = l + (r - l) / 2;
if (arr[mid] == target)
return mid;
if (target > arr[mid])
l = mid + 1; //target在[mid+1...r)中
else{
r = mid ; //target在[l...mid)中
}
}
return -1;
}
完整代码
#include <iostream>
#include<algorithm>
#include<cassert>
#include<ctime>
using namespace std;
namespace myUntil{
int *generateRandomArray(int n, int rangeL, int rangeR){
assert(n > 0 && rangeL <= rangeR);
int *arr = new int[n];
srand(time(NULL));
for (int i = 0; i < n; i++){
arr[i] = rand() % (rangeL - rangeL);
}
return arr;
}
int *generateRandomArray(int n){
assert(n > 0);
int *arr = new int[n];
for (int i = 0; i < n; i++)
arr[i] = i;
return arr;
}
}
#include<iostream>
#include<cmath>
#include<cassert>
#include<ctime>
#include"myUntil.h"
using namespace std;
template<typename T>
int binarySearch(T arr[], int n, T target){
int l = 0, r = n -1; //[l....r]的范围内寻找target
while (l <= r) { //当 l== r时, 区间[l....r]依旧有效、
int mid = l + (r - l) / 2;
if (arr[mid] == target)
return mid;
if (target > arr[mid])
l = mid + 1; //target在[mid+1...r]中
else{
r = mid - 1; //target在[l...mid-1]中
}
}
return -1;
}
template<typename T>
int binarySearch2(T arr[], int n, T target){
int l = 0, r = n ; //[l....r)的范围内寻找target
while (l < r) { //当 l== r时, 区间[l....r)依旧有效、
int mid = l + (r - l) / 2;
if (arr[mid] == target)
return mid;
if (target > arr[mid])
l = mid + 1; //target在[mid+1...r)中
else{
r = mid ; //target在[l...mid)中
}
}
return -1;
}
int main() {
int n = 10000000;
int *data = myUntil::generateRandomArray(n);
clock_t startTime = clock();
for (int i = 0; i < n; i++){
assert(i == binarySearch2(data, n, i));
}
clock_t endTime = clock();
cout << "binarySearch test complete." << endl;
cout << "Time Cost: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s" << endl;
system("pause");
return 0;
}