2025/3/17学习日志

二分查找找最大值算法(很短)

#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);
}

明天继续归并排序 自己写一遍 今天学到这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值