【剑指Offer】和为S的两个数。输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

题目描述:

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。
输出描述:
对应每个测试案例,输出两个数,小的先输出。

看到这个题其实看起来是个很简单的题目,我首先想到的思路就是:

思路

首先明白该数组是个递增数组。
1-用两个指针指该数组的两头 pl,ph
2-当两个指针所指的值之和>S时,ph–;之和<S时,pl++;当和==S时,把pl,ph push_back到新数组中,记住pl和ph的乘积。
3-若下一次循环步骤2的乘积小于之前记住的乘积则对新数组进行clear操作,重新push_back。

注:代码一根据这个步骤写,本地测试通过,牛客给出段错误。于是对代码进行了另外一种思路,但是如果有大佬知道我第一个代码为什么错误,欢迎评论。

代码二思路:
1-用两个指针指该数组的两头 pl,ph
2-当两个指针所指的值之和>S时,ph–;之和<S时,pl++;当和==S时,把*pl,ph push_back到新数组中,直接break。(原因:因为该数组是个递增数组,两个指针从两头开始,那么第一次相加等于S的两个数字相差的最远,我们都知道若和一定,两数相差越远越小。1和8,3和6,4和5;1和8 差值最大那么18也是最小的。)

代码一:本地通过,牛客出现段错误

class Solution {
public:
	vector<int> FindNumbersWithSum(vector<int> array, int sum) {
		vector<int> result;
		int len = array.size();
		int* pl = &array[0];
		int* ph = &array[len - 1];
		int res = array[len - 1] * array[len - 2];
		int i = len - 1;
		while (ph > pl) {
			int tmp, tmp2;
			tmp = *ph + (*pl);
			while (tmp > sum&& ph > pl){
				ph--;
				tmp = *ph + (*pl);
			}
			while (tmp < sum&& ph > pl){
				pl++;
				tmp = *ph + (*pl);
			}
			if(tmp==sum) {
				tmp2 = (*pl) * (*ph);
				if (tmp2 < res) {
					res = tmp2;
					if (!result.empty())
						result.clear();
					result.push_back(*pl);
					result.push_back(*ph);
				}
				ph--;
			}
		}
		return result;
	}
};

代码二:本地和牛客都通过

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        vector<int> res;
        int n = array.size();
        int *pl = &array[0], *ph=&array[n-1];
        while (pl < ph) {
            if (*pl + *ph == sum) {
                res.push_back(*pl);
                res.push_back(*ph);
                break;
            }
            while (pl < ph && *pl + *ph > sum) --ph;
            while (pl < ph && *pl + *ph < sum) ++pl;
        }
        return res;
    }
};

段错误问题找到

对于代码一
我们把if和等于sum放在两个while前面牛客就会显示正确。
同样如果对于代码二 如果把if 放在两个while 后面也会出现和代码一相同的错误。正确代码一如下:

class Solution {
public:
    vector<int> FindNumbersWithSum(vector<int> array,int sum) {
        vector<int> result;
        int len = array.size();
        int *pl = &array[0];
        int* ph = &array[len - 1];
        int res = array[len - 1] * array[len - 2];
        int i = len - 1;
        while (ph > pl) {
            int  tmp;
            if (*ph + (*pl) == sum) {
                tmp = (*pl) * (*ph);
                if (tmp < res) {
                    res = tmp;
                    if (!result.empty())
                        result.clear();
                    result.push_back(*pl);
                    result.push_back(*ph);
                }
                ph--;
            }
            while (*ph + (*pl) > sum&& ph > pl) {
                ph--;
            }
            while (*ph + (*pl) < sum && ph > pl) {
                pl++;
            }
        }
        return result;
    }
};
发布了57 篇原创文章 · 获赞 28 · 访问量 4114

猜你喜欢

转载自blog.csdn.net/weixin_41747893/article/details/104742563