之前遇到的一道算法題,這里記錄一下。
算法思想:因為是有序的,所以我們用s存放第一個元素的下標,用e存放最后一個元素的下標,那么arr[s] 就是所有元素中最小的,arr[e]就是所有元素中最大的,所以我們判斷arr[s] + arr[e] - sum的值是否大於0,如果大於0那就說明 arr[e] 太大了,那么就e--。如果小於0,arr[s] 太小了,那就s++。這個時候判斷是否距離比上一個我們記錄的距離更小,更小的話就更新,距離是|arr[s] + arr[e] - sum|這么算出來的。
因為沒在oj或者LeetCode上找到,因此我也不確定代碼有沒有特殊值遺漏,不過大致思想是這樣子的。程序能滿足題目的要求
代碼如下:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int arr[10000];
int n,sum;
scanf("%d %d",&n,&sum);
for(int i=0;i<n;i++) {
scanf("%d",&arr[i]);
}
int s=0,e=n-1;
int dis = abs(arr[n-1] + arr[0] - sum);
int result = dis;
int resa,resb;
int flag = 0;
while(s<e){
dis = arr[s] + arr[e] - sum;
if(dis>0){
if(abs(dis)<result) {
result = abs(dis);
resa = arr[s];
resb = arr[e];
}
e--;
}else if(dis<0){
if(abs(dis)<result) {
result = abs(dis);
resa = arr[s];
resb = arr[e];
}
s++;
}else {
printf("%d %d",arr[s],arr[e]);
flag = 1;
break;
}
}
if(flag==0) {
printf("%d %d",resa,resb);
}
return 0;
}
因為是從頭和尾同時開始往中間走,他倆匯合即得到答案,故時間復雜度為O(n)。