剑指offer面试题57:和为S的两个数字

索引请参考:系列目录
题目:

  • 输入一个递增排序的数字和一个数字S,使得他们的和正好是S。如果有多对数字的和等于S,输出2个乘积最小的。
  • 示例:
  • 输入: {1,2,3,3,4,5,6} 和 6
  • 输出: {2,4}

分析:
思路1:

  • 利用容器set或者map(multi)的成员函数
  • (1)将数组放入set或者map(multi)中
  • (2)遍历 + 判断
m_elem = s - array[i]
if(multimap::count(m_elem))
	//放入数组中
  • 如果结果数组中的个数大于1,找到2个数乘积最小的输出

思路2:

  • 遍历 + 标准模板库中算法中的find()算法

思路3:双指针思想

  • (1)在数组中选择两个数
    • 和等于输入S ——>找到要找的两个数字
    • 和小于S——>希望2个数字的和再大点。由于数组已经排序好了,可以考虑较小的数组后面的数字
    • 和大于S——>选择较大数字前面的数字(具体请参考代码)

思路1:

std::vector<int> FindNumbersWithSum1(const std::vector<int> & array, int sum) {

	std::multiset<int> coll;
	for (auto elem : array)
		coll.insert(elem);
	std::vector<int>result;
	for (auto elem : coll)
	{
		int m_elem = sum - elem;
		if (coll.count(m_elem))
		{
			if (result.empty())
			{
				result.push_back(elem);
				result.push_back(m_elem);
			}
			else if (result[0] * result[1] > elem * m_elem)
			{
				result.clear();
				result.push_back(elem);
				result.push_back(m_elem);
			}		
		}
	}
	return result;
}

牛客运行结果:
在这里插入图片描述
思路2:

auto end = array.end();
	std::vector<int>result;
	for (auto elem : array)
	{
		auto pos = std::find(array.begin(), array.end(), sum - elem);
		if (pos != end)
		{
			if (!result.empty())
			{
				int a = result[0];
				int b = result[1];
				if (a * b > *pos * elem)
				{
					result.clear();
					result.push_back(elem);
					result.push_back(*pos);
				}
			}
			else
			{
				result.push_back(elem);
				result.push_back(*pos);
			}

		}
	}
	return result;

牛客运行结果:
在这里插入图片描述

思路3:

if (array.empty())
		return{};

	int temp = INT_MAX;
	std::pair<int, int>ret;

	int i = 0, j = array.size();
	while (i < j)
	{
		if (array[i] + array[j - 1] == sum)
		{
			if (array[i] * array[j - 1] < temp)
			{
				temp = array[i] * array[j - 1];
				ret = { i , j - 1 };	
			}
			i++;
			j--;
		}

		else if (array[i] + array[j - 1] < sum)
			++i;
		else
			--j;
	}

	if (ret.first == ret.second)
		return{};
	return std::vector<int>({ array[ret.first],array[ret.second] });

在这里插入图片描述

评注:理论上应该是双指针的形式时间复杂度更低一些,但是实际牛客测试结果是利用STL容器内部的成员函数运行时间更快。具体原理有待理解。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值