#include <iostream>
#include <cmath>
#include <climits>
using namespace std;
void FindClosestPair(int *a,int n,int sum)
{
int i=0,j=n-1;
int dif=INT_MAX;
int Start=0,End=0; //存储输出的元素
while(i<n&&j>i)
{
if(abs(a[i]+a[j]-sum)<dif)
{
Start=a[i];
End=a[j];
dif=abs(a[i]+a[j]-sum);
}
else if(a[i]+a[j]<sum)
{ //若当前差值依然是最小的,并且两数之和比期望值小,
//说明应该增大左边的值
i++;
}
else
{
j--;
}
}
cout<<Start<<" "<<End<<endl;
}
int main()
{
int a[]={-5,-1,0,1,4,5,7,9};
FindClosestPair(a,8,8);
return 0;
}
head在什么情况下可能移动到i的右边?假设head已经移动到了i的右边,即head > i且numbers [head] > numbers [i] ,根据算法规则,只有当numbers [head] + numbers [tail] < target时,head才会右移,所以 numbers [tail] < target - numbers [head] < target - numbers [i] = numbers [j] ,意味着tail一定出现在j的左边。
那tail在什么情况下可能移动到j的左边?同理,只有当head在i的右边时才可能发生。
因为一开始head在i的左边,tail在j的右边,算法每次只移动head或tail,所以不可能出现某一时刻经过算法移动后,head移动到i的右边而同时tail移动到j的左边的情况。证明结束。
public void minDiff(int[] nums, int sum) {
int low = 0;
int high = nums.length - 1;
int diff = Integer.MAX_VALUE;
int a = 0;
int b = 0;
while (low < high) {
if (Math.abs(nums[low] + nums[high] - sum) < diff) {
diff = Math.abs(nums[low] + nums[high] - sum);
a = nums[low];
b = nums[high];
} else if (nums[low] + nums[high] > sum) {
high --;
} else {
low ++;
}
}
System.out.printf("a,b is %d, %d", a, b);
} public class ABSum {
public static void main(String[] args) {
int[] nums = {-5, -1, 0, 1, 4, 5, 7, 9};
getAB(nums, 6);
int[] nums2 = {1, 3, 4, 5, 6, 7, 8, 9};
getAB(nums2, 4);
}
public static void getAB(int[] nums, int sum) {
int left = 0, right = nums.length - 1;
int dif = Integer.MAX_VALUE;
while(left < nums.length - 1 && left < right) {
if(dif > Math.abs(nums[left] + nums[right] - sum)) {
dif = Math.abs(nums[left] + nums[right] - sum);
}
if(dif == 0) {
break;
}
if(nums[left] + nums[right] > sum) {
right--;
}else {
left++;
}
}
System.out.println(nums[left] + " " + nums[right]);
}
}