给定排序数组array和给定值k,不重复打印array中累加和为k的不降序二元与三元组, 比如给定array={-8,-4,-3,0,1,2,4,5,8,9},k=10,打印结果为
1 9
2 8
思路如下:
使用两个指针,left指向最左边的节点,right指向最右边的节点,然后我们不断的向中间压缩,打印
如果array[left]+array[right]=k 则打印 left++, right--(为什么,因为要打印非重复二元组,如果left不动,只有right--,则right--后有两种可能,和以前的一样,比以前的小,任何一种可能都是不符合条件的)
如果array[left]+array[right]<k,则代表要加的值大了,要缩小,故right--
如果array[left]+array[right]>k,则代表要加的值小了,故增大,left++
还有一点要注意
我们要打印的是不重复的二元组
如果是 1 1 1 9
则1 9 会打印三次
怎么打印一次呢?
那就是判断 array【left】和array【left-1】是否相等
如果相等,就跳过
如果不等,则可以打印
尤其要注意,打印的是数值不重复的二元三元组
在打印三元组的时候,和二元类似,对数组进行遍历,遍历到i的时候,对i后面的子数组调用打印二元函数
有个情况
x x y z w
分析第一个x时候,对后面子数组,xyzw进行二元分析
分析第二个x时候,对后面子数组进行二元分析
因为要打印非重复的数组,所以分析第一个时候,其实就是相当于对后面的子数组 yzw进行分析
#include <iostream>
using namespace std;
int arr[]={-8,-4,-3,0,1,2,4,5,8,9};
int k=10;
int cur;
bool flag=false;
void PrintTwoDuples(int begin,int end)
{
int left=begin;
int right=end;
while(left<right)
{
if(arr[left]+arr[right]==k)
{
if(left==0||arr[left]!=arr[left-1])
{
if(flag)
cout<<arr[cur]<<" ";
cout<<arr[left]<<" "<<arr[right]<<endl;
}
left++;
right--;
}
else if(arr[left]+arr[right]<k)
{
left++;
}
else
{
right--;
}
}
}
void PrintTriples(int begin,int end)
{
int i;
flag=true;
for(i=begin;i<=end-2;i++)
{
k=10;
cur=i;
k=k-arr[i];
if(i==0||arr[i]!=arr[i-1])
PrintTwoDuples(i+1,end);
}
}
int main()
{
PrintTwoDuples(0,9);
PrintTriples(0,9);
return 0;
}