基础算法---二分法

二分法描述

对于区间[a,b]上连续不断且f(a)·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫二分法。

示例1
寻找是否有4这个值有输出yes 否则 no
输入

5
1
2
3
4
5

输出

yes

代码

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

int main()
{
	int n,m;
	cin >> n;
	int y = 4;
	int a[1001];
	//初始化
	memset(a,0,sizeof(a));
	for (int i = 0; i < n;i++) 
	{
		cin >> m;
		a[i] = m;
	};
	//进行排序
	sort(a, a + n - 1);
	int l, r, mid;//左边。右边,中间
	l = 0;
	r = n - 1;
	int flag = 1;
	while (r>=l)
	{
		mid = (l + r) / 2;
		if (a[mid] > y) r = mid - 1;
		else l = mid + 1;
		if (a[mid] == y) 
		{
			cout << "YES" << endl;
			flag = 0;
			break;
		};
	}
	if (flag) cout << "NO" << endl;
};

思路

就是或者中间大小的值,如果大,则缩小区间,那值一定在左边,那另r = mid -1; 相反则 l = mid + 1; 时间复杂度为log n;

示例2

问题描述

输入n ( n≤100,000)个整数,找出其中的两个数,它们之和等于整数m(假定肯定有解)。题中所有整数都能用int 表示。下面的计算我们假色m = 10

输入

6
9
1
2
3
8
7

输出

1 9
2 8
3 7

代码

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

int main()
{
	int n = 0;
	int a[100001];
	cin >> n;
	int m;
	int y = 10;
	for (int i = 0; i < n; i++)
	{
		cin >> m;
		a[i] = m;
	}
	//排序之后进行二分求解法
	sort(a,a+n);
	int l, r, mid;
	l = 0;
	r = n - 1;
	for (int i = 0; i < n; i++) 
	{
		l = i + 1;
		while (r>=l)
		{
			mid = (r + l) / 2;
			if (a[i] + a[mid] > y)
				r = mid - 1;
			else
				l = mid + 1;

			if (a[i] + a[mid] == y) 
			{
				cout << a[i] << "\t" <<a[mid] << endl;
				break;
			};
		}
	};
	
}
	

思路

取排序后的第一个值,然后在根据2分查找法,查找剩下的值,判断是否和取的数加起来等于需要等于的数,如果有则打印,以此类推,时间复杂度为(nlogn)

总结

二分查找法适用于单调函数的查找。相比于传统的循环,效率要好很多。希望下次在遇见类似的题目时,对于基础算法的使用更加灵活,使得解题更加快速。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值