【劍指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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章