二分查找找最大值算法(很短)
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class solution
{
int lcz_find(int* arr, int beg, int end)
{
if (beg == end)
return arr[beg];
else if (beg == end - 1)
return max(arr[beg], arr[end]);
int mid = beg + (end - beg) / 2;
int left_max = lcz_find(arr, beg, mid);
int right_max = lcz_find(arr,min(mid+1, end),end);
return max(left_max, right_max);
}
};
写一个二分查找的非递归过程。
int returnTarget(int* arr,int n,int target)
{
int left = 0, right = n-1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == target)
return mid;
else
{
if (arr[mid] > target)
right = mid - 1;
else if (arr[mid] < target)
left = mid + 1;
}
}
return -1;//unfound;
}
一些狗屁结论:
定理表明:任何一种以比较为基础的算法,其最坏情况下的计算时间都不可能低于 o(logn),也就是不可能存在其最坏情况下计算时间比二分检索算法的计算时间数量级还低的算法。
二分检索是解决有序表检索问题最坏情况下最优的算法。
根据4.2节开始所给出的二分查找策略,写一个二分查找的递归过程。
int BS_recursion(int* arr, int left, int right,int target)
{
int mid = left + (right - left) / 2;
if (left > right)return -1;
if (arr[mid] == target)return mid;
else if (arr[mid] > target)return BS_recursion(arr, left, mid - 1, target);
else return BS_recursion(arr, mid+1, right, target);
}
设计一个“三分”查找算法,它首先检查n/3处的元素是否等于某个x的值,然后检查2n/3处的元素。这样,或者找到x,或者把集合缩小到原来的1/3。分析算法在各种情况下的计算复杂度。
每次看落在这三段哪一个区间就行了。和二分查找很像。关键是看复杂度
int returnTarget(int* arr, int n, int target)
{
int left = 0, right = n - 1;
while (left <= right)
{
int mid1 = left + (right - left) / 3;
int mid2 = left + (right - left) * 2 / 3;
if (arr[mid1] == target) return mid1;
else if (arr[mid2] == target) return mid2;
else if (arr[mid1] > target)right = mid1 - 1;
else if (arr[mid2] < target)left = mid2 + 1;
else if (arr[mid1] < target && target < arr[mid2])left = mid1 + 1, right = mid2 - 1;
}
return -1;//unfound;
}
时空复杂度的分析:
归并排序
原文连接:归并排序
void merge(int* arr, int left, int mid, int right) {
int n1 = mid - left + 1; // 左数组的长度
int n2 = right - mid; // 右数组的长度
// 创建临时数组
int* L = new int[n1];
int* R = new int[n2];
// 复制数据到临时数组
for (int i = 0; i < n1; i++) {
L[i] = arr[left + i];
}
for (int j = 0; j < n2; j++) {
R[j] = arr[mid + 1 + j];
}
// 合并两个有序数组
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// 复制剩余的元素
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
// 释放临时数组
delete[] L;
delete[] R;
}
void mergeSort(int* arr, int left, int right) {
if (left >= right) {
return; // 递归终止条件
}
// 找到中间位置
int mid = left + (right - left) / 2;
// 递归排序左右两部分
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 合并两个有序数组
merge(arr, left, mid, right);
}
明天继续归并排序 自己写一遍 今天学到这里。