AcWing 自动补全 二分

题目链接

先上AC代码。
参开代码:

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;

string s[100005];
unordered_map<string, int> m;
bool check(string a, string b)
{
	if (a.size() < b.size()) return false;
	for (int i = 0; i < b.size();i++)
		if (a[i] != b[i]) return false;
	return true;
}

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	int w, n;
	cin >> w >> n;
	for (int i = 0; i < w; i++)
	{
		cin >> s[i];
		m[s[i]] = i + 1;
	}
	sort(s, s + w);
	string str;
	int num;
	for (int i = 0; i < n; i++)
	{
		cin >> num >> str;
		int l = 0, r = w;
		int mid = (l + r) >> 1;
		while (l <= r)
		{
			if (s[mid] >= str) r = mid - 1;
			else l = mid + 1;
			mid = (l + r) >> 1;
		}
		if (s[mid + num].substr(0, str.size()) == str) cout << m[s[mid + num]] << endl;
		else cout << -1 << endl;
	}
	return 0;
}

思路:
基本思路是先对字典中的字符串sort排序,然后使用查找的方法确定找到的字符串开始计算的第n个字符串是否与待自动补全的字符串匹配,若存在,输出第n个字符串的初始顺序;若不存在,则输出-1。
而对于查找,若使用暴力方法,则会导致查找超时。当查找超时时,我们不难想到可以用时间复杂度为logn的二分查找,代码如下所示:

while (l <= r)
		{
			if (s[mid] >= str) r = mid - 1;
			else l = mid + 1;
			mid = (l + r) >> 1;
		}

上面是基础的二分查找写法,起初我对第三行的大于等于并不理解,写成了大于,导致我只过了少部分测试店。后来回想,发现:若是大于号,当字典中有和待匹配字符串相同的字符串,则会导致查找的字符串并不是满足条件的第一个字符串。又因为题目说字典中的字符串不可能相同,因此大于等于号查找出来的字符串一定是当前字典序中第一个符合条件的字符串。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值