题目描述
给定排序数组arr和整数k,不重复打印arr中所有相加和为k的严格升序的三元组
例如, arr = [-8, -4, -3, 0, 1, 2, 4, 5, 8, 9], k = 10,打印结果为:
-4 5 9
-3 4 9
-3 5 8
0 1 9
0 2 8
1 4 5
[要求]
时间复杂度为O(n^2),空间复杂度为O(1)。
输入描述
第一行有两个整数n, k
接下来一行有n个整数表示数组内的元素
输出描述
输出若干行,每行三个整数表示答案
按三元组从小到大的顺序输出(三元组大小比较方式为每个依次比较三元组内每个数)
示例1
输入:
10 10
-8 -4 -3 0 1 2 4 5 8 9
输出:
-4 5 9
-3 4 9
-3 5 8
0 1 9
0 2 8
1 4 5
解题思路
该题目跟之前的 程序员代码面试指南—003不重复打印排序数组中相加和为给定值的所有二元组 类似,只是该题需要输出三元组。
我们可以将其中一个数固定,然后用 k 减去这个数字,之后就变成二元组的问题。二元组的解题思路为双指针解法,具体可以参考上面提到的博客。
注意:
遍历每一个数字的时候,只需要遍历到倒数第三个即可。
牛客网测试用例的坑:
在使用双指针之前需要判断连续两个数字是否相等,因为三元组中,前两个数字相等,测试用例会判断错误。
代码实现
/*
* @Description: 不重复打印排序数组中相加和为给定值的所有三元组
* @Author:
* @Date: 2020-10-18 19:37:33
* @LastEditTime: 2020-10-18 20:10:19
* @LastEditors: Please set LastEditors
*/
#include<iostream>
#include<vector>
using namespace std;
int main(){
int n,k;
cin >> n >> k;
vector<int> arr(n);
for(int i = 0;i < n;i++){
cin >> arr[i];
}
for(int i = 0;i < n - 2;i++){
if(i == 0 || arr[i] != arr[i - 1]){//需要注意判断。
int left = i + 1;
int right = arr.size() - 1;
while (left < right)
{
if (arr[left] + arr[right] < k - arr[i])
{
left++;
}
else if (arr[left] + arr[right] > k - arr[i])
{
right--;
}
else
{
if (arr[left] != arr[left - 1])
{
cout << arr[i] << " " << arr[left] << " " << arr[right] << endl;
}
left++;
right--;
}
}
}
}
system("pause");
return 0;
}