首页 > 试题广场 >

不重复打印排序数组中相加和为给定值的所有三元组

[编程题]不重复打印排序数组中相加和为给定值的所有三元组
  • 热度指数:12712 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定排序数组arr和整数k,不重复打印arr中所有相加和为k的严格升序的三元组
例如, arr = [-8, -4, -3, 0, 1, 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
其中三元组1 1 8不满足严格升序所以不打印
[要求]
时间复杂度为空间复杂度为


输入描述:
第一行有两个整数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
示例2

输入

11 10
-8 -4 -3 0 1 1 2 4 5 8 9

输出

-4 5 9
-3 4 9
-3 5 8
0 1 9
0 2 8
1 4 5
示例3

输入

11 10
-8 -4 -3 0 1 1 2 4 4 8 9

输出

-3 4 9
0 1 9
0 2 8

备注:
import java.util.*;
public class Main {
    public static void main(String[]args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int k = scanner.nextInt();

        int arr[] = new int[n];
        for (int i = 0; i < n; i++)
            arr[i] = scanner.nextInt();
        int l = 0;
        int r = n - 1;
        int m = l + 1;
        while (l < r - 1) {
            //l++;
            if (l == 0 || arr[l] != arr[l - 1]) {
                //l不重复在比较m,r
                m = l + 1;
                r = n - 1;
                while (m < r) {
                    if (arr[l] + arr[m] + arr[r] == k) {
                        if ((m == 0 || arr[m] != arr[m - 1]) & arr[m] != arr[r])
                            System.out.println(arr[l] + " " + arr[m] + " " + arr[r]);
                        m++;
                        r--;
                    } else if (arr[l] + arr[m] + arr[r] < k)
                        m++;
                    else r--;
                }
            }
            l++;
        }
    }
}

发表于 2022-06-08 07:55:10 回复(0)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int K = sc.nextInt();
        int []arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
        printByOrder(K , arr);
    }

    private static void printByOrder(int k, int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            if (i >= 1 &&arr[i] == arr[i - 1]) continue;
            int left = i + 1;
            int right = arr.length - 1;
            while(left < right){
                if (arr[i] + arr[left] + arr[right] < k) left ++;
                else if (arr[i] + arr[left] + arr[right] > k) right--;
                else {
                    if (arr[left] != arr[right] && arr[left] != arr[left -1]){
                        System.out.println(arr[i] + " " + arr[left] + " " + arr[right]);
                    }
                    left ++;
                    right--;
                }
            }
        }
    }
}

发表于 2022-05-25 15:38:46 回复(0)
固定第一个数,后两个数用双指针法得到,在移动指针的时候记得与前一次指针所指的数对比,两者不能相等。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] params = br.readLine().split(" ");
        int n = Integer.parseInt(params[0]), k = Integer.parseInt(params[1]);
        params = br.readLine().split(" ");
        int[] nums = new int[n];
        for(int i = 0; i < n; i++) nums[i] = Integer.parseInt(params[i]);
        for(int i = 0; i < n - 2; i++){
            if(i > 0 && nums[i] == nums[i - 1]) continue;     // 第一元素去重
            int target = k - nums[i];
            int left = i + 1;
            while(nums[left] == nums[i] && left < n - 1) left ++;       // 第二个元素不能等于第一个元素
            int right = n - 1;
            while(left < right){
                if(nums[left] + nums[right] > target){
                    right --;
                }else if(nums[left] + nums[right] < target){
                    left ++;
                }else{
                    if(nums[left] < nums[right]) System.out.println(nums[i] + " " + nums[left] + " " + nums[right]);
                    left ++;
                    right --;
                    while(nums[left] == nums[left - 1]) left ++;         // 第二元素去重
                    while(nums[right] == nums[right + 1]) right --;      // 第三元素去重
                }
            }
        }
    }
}

发表于 2021-11-19 16:41:06 回复(0)
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] s = br.readLine().split(" ");
        int n = Integer.parseInt(s[0]);
        int k = Integer.parseInt(s[1]);
        int[] mat = new int[n];
        s = br.readLine().split(" ");
        for (int i = 0; i < n; i++) {
            mat[i] = Integer.parseInt(s[i]);
        }
        int[][] res = new int[n][3];
        int index = 0;
        for (int i = 0; i < n - 2; i++) {
            int curSum = k - mat[i];
            int lo = i + 1, hi = n - 1;
            while (lo < hi) {
                int val1 = mat[lo], val2 = mat[hi];
                if (mat[lo] + mat[hi] == curSum) {
                    res[index][0] = mat[i];
                    res[index][1] = mat[lo];
                    res[index][2] = mat[hi];
                    index++;
                    while (lo < hi && mat[lo] == val1) lo++;
                    while (lo < hi && mat[hi] == val2) hi--;
                } else if (mat[lo] + mat[hi] < curSum) {
                    while (lo < hi && mat[lo] == val1) lo++;
                } else {
                    while (lo < hi && mat[hi] == val2) hi--;
                }
            }
        }
        for (int i = 0; i < index; i++) {
            System.out.println(res[i][0] + " " + res[i][1] + " " + res[i][2]);
        }
    }
}
为什么报错说我数组越界? 求解...

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 999

at Main.main(Main.java:22)

发表于 2020-09-18 20:15:34 回复(0)
跳过重复的数据果然通过了
import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int k = scanner.nextInt();

        int[] arr = new int[n];
        for (int i = 0; i < n; i++) {
            arr[i] = scanner.nextInt();
        }

        for (int i = 0; i < n-1; i++){
            if (arr[i] == arr[i+1]){    //跳过重复的数
                continue;
            }
            solve(arr,i+1,arr.length-1,k-arr[i],arr[i]);
        }
    }

    public static void solve(int[] arr, int pre, int behind, int value, int now){
        int left = pre;
        int right = behind;
        while (left < right) {
            if (arr[left] + arr[right] == value) {
                while (arr[left] == arr[left + 1]) {
                    left++;
                }
                while (arr[right] == arr[right - 1]) {
                    right--;
                }
                System.out.println(now + " " + arr[left] + " " + arr[right]);
                left++;
                right--;
            } else if (arr[left] + arr[right] > value) {
                right--;
            } else {
                left++;
            }
        }
    }
}


发表于 2020-09-07 14:49:17 回复(0)
import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext())
        {
            int n = scanner.nextInt();
            int target = scanner.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; i++)
            {
                arr[i] = scanner.nextInt();
            }

            findThreeArray(arr, target);
        }
    }

    private static void findThreeArray(int[] arr, int target)
    {
        if (arr.length < 3)
            return;

        for (int i = 0; i < arr.length - 3; i++)
        {
            int begin = i + 1;
            int end = arr.length-1;
            int newTarget = target - arr[i];

            if (arr[i] == arr[i + 1])
            {
                continue;
            }

            while (begin < end)
            {
                if (arr[begin] + arr[end] > newTarget)
                    end--;
                else if (arr[begin] + arr[end] < newTarget)
                    begin++;
                else
                {
                    System.out.println(arr[i] + " " + arr[begin] + " " + arr[end]);
                    if (arr[begin] == arr[begin + 1])
                        begin++;
                    if (arr[end] == arr[end - 1])
                        end--;
                    begin++;
                    end--;
                }
            }
        }
    }
}

发表于 2020-03-24 19:54:45 回复(0)