列表

详情


1534. 统计好三元组

给你一个整数数组 arr ,以及 abc 三个整数。请你统计其中好三元组的数量。

如果三元组 (arr[i], arr[j], arr[k]) 满足下列全部条件,则认为它是一个 好三元组

其中 |x| 表示 x 的绝对值。

返回 好三元组的数量

 

示例 1:

输入:arr = [3,0,1,1,9,7], a = 7, b = 2, c = 3
输出:4
解释:一共有 4 个好三元组:[(3,0,1), (3,0,1), (3,1,1), (0,1,1)] 。

示例 2:

输入:arr = [1,1,2,2,3], a = 0, b = 0, c = 1
输出:0
解释:不存在满足所有条件的三元组。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int countGoodTriplets(vector<int>& arr, int a, int b, int c) { } };

python3 解法, 执行用时: 47 ms, 内存消耗: 17.8 MB, 提交时间: 2025-04-14 07:51:29

class Solution:
    def countGoodTriplets(self, arr: List[int], a: int, b: int, c: int) -> int:
        ans = 0
        mx = max(arr)
        s = [0] * (mx + 2)  # cnt 数组的前缀和
        for j, y in enumerate(arr):
            for z in arr[j + 1:]:
                if abs(y - z) > b:
                    continue
                l = max(y - a, z - c, 0)
                r = min(y + a, z + c, mx)
                ans += max(s[r + 1] - s[l], 0)  # 如果 l > r + 1,s[r + 1] - s[l] 可能是负数
            for v in range(y + 1, mx + 2):
                s[v] += 1  # 把 y 加到 cnt 数组中,更新所有受到影响的前缀和
        return ans

cpp 解法, 执行用时: 0 ms, 内存消耗: 12 MB, 提交时间: 2025-04-14 07:51:08

class Solution {
public:
    int countGoodTriplets1(vector<int>& arr, int a, int b, int c) {
        int n = arr.size(), ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (abs(arr[i] - arr[j]) <= a && abs(arr[j] - arr[k]) <= b && abs(arr[i] - arr[k]) <= c) {
                        ans++;
                    }
                }
            }
        }
        return ans;
    }

    int countGoodTriplets(vector<int>& arr, int a, int b, int c) {
        int n = arr.size(), mx = ranges::max(arr), ans = 0;
        vector<int> s(mx + 2); // cnt 数组的前缀和
        for (int j = 0; j < arr.size(); j++) {
            int y = arr[j];
            for (int k = j + 1; k < arr.size(); k++) {
                int z = arr[k];
                if (abs(y - z) > b) {
                    continue;
                }
                int l = max({y - a, z - c, 0});
                int r = min({y + a, z + c, mx});
                ans += max(s[r + 1] - s[l], 0); // 如果 l > r + 1,s[r + 1] - s[l] 可能是负数
            }
            for (int v = y + 1; v < mx + 2; v++) {
                s[v]++; // 把 y 加到 cnt 数组中,更新所有受到影响的前缀和
            }
        }
        return ans;
    }
};

java 解法, 执行用时: 3 ms, 内存消耗: 40.6 MB, 提交时间: 2025-04-14 07:50:39

class Solution {
    public int countGoodTriplets1(int[] arr, int a, int b, int c) {
        int n = arr.length;
        int ans = 0;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int k = j + 1; k < n; k++) {
                    if (Math.abs(arr[i] - arr[j]) <= a && Math.abs(arr[j] - arr[k]) <= b && Math.abs(arr[i] - arr[k]) <= c) {
                        ans++;
                    }
                }
            }
        }
        return ans;
    }

    public int countGoodTriplets(int[] arr, int a, int b, int c) {
        int mx = 0;
        for (int x : arr) {
            mx = Math.max(mx, x);
        }
        int[] s = new int[mx + 2]; // cnt 数组的前缀和

        int ans = 0;
        for (int j = 0; j < arr.length; j++) {
            int y = arr[j];
            for (int k = j + 1; k < arr.length; k++) {
                int z = arr[k];
                if (Math.abs(y - z) > b) {
                    continue;
                }
                int l = Math.max(Math.max(y - a, z - c), 0);
                int r = Math.min(Math.min(y + a, z + c), mx);
                ans += Math.max(s[r + 1] - s[l], 0); // 如果 l > r + 1,s[r + 1] - s[l] 可能是负数
            }
            for (int v = y + 1; v < s.length; v++) {
                s[v]++; // 把 y 加到 cnt 数组中,更新所有受到影响的前缀和
            }
        }
        return ans;
    }
}

golang 解法, 执行用时: 2 ms, 内存消耗: 4.1 MB, 提交时间: 2025-04-14 07:50:09

func countGoodTriplets1(arr []int, a, b, c int) (ans int) {
    n := len(arr)
    for i, x := range arr {
        for j := i + 1; j < n; j++ {
            for k := j + 1; k < n; k++ {
                if abs(x-arr[j]) <= a && abs(arr[j]-arr[k]) <= b && abs(x-arr[k]) <= c {
                    ans++
                }
            }
        }
    }
    return
}

func countGoodTriplets(arr []int, a, b, c int) (ans int) {
    mx := slices.Max(arr)
    s := make([]int, mx+2) // cnt 数组的前缀和
    for j, y := range arr {
        for _, z := range arr[j+1:] {
            if abs(y-z) > b {
                continue
            }
            l := max(y-a, z-c, 0)
            r := min(y+a, z+c, mx)
            ans += max(s[r+1]-s[l], 0) // 如果 l > r + 1,s[r + 1] - s[l] 可能是负数
        }
        for v := y + 1; v < mx+2; v++ {
            s[v]++ // 把 y 加到 cnt 数组中,更新所有受到影响的前缀和
        }
    }
    return
}

func abs(x int) int { if x < 0 { return -x }; return x }

javascript 解法, 执行用时: 5 ms, 内存消耗: 54.8 MB, 提交时间: 2025-04-14 07:49:34

/**
 * @param {number[]} arr
 * @param {number} a
 * @param {number} b
 * @param {number} c
 * @return {number}
 */
var countGoodTriplets1 = function(arr, a, b, c) {
    const n = arr.length;
    let ans = 0;
    for (let i = 0; i < n; i++) {
        for (let j = i + 1; j < n; j++) {
            for (let k = j + 1; k < n; k++) {
                if (Math.abs(arr[i] - arr[j]) <= a && Math.abs(arr[j] - arr[k]) <= b && Math.abs(arr[i] - arr[k]) <= c) {
                    ans++;
                }
            }
        }
    }
    return ans;
};

var countGoodTriplets = function(arr, a, b, c) {
    const mx = Math.max(...arr);
    const s = Array(mx + 2).fill(0); // cnt 数组的前缀和
    let ans = 0;
    for (let j = 0; j < arr.length; j++) {
        const y = arr[j];
        for (let k = j + 1; k < arr.length; k++) {
            const z = arr[k];
            if (Math.abs(y - z) > b) {
                continue;
            }
            const l = Math.max(y - a, z - c, 0);
            const r = Math.min(y + a, z + c, mx);
            ans += Math.max(s[r + 1] - s[l], 0); // 如果 l > r + 1,s[r + 1] - s[l] 可能是负数
        }
        for (let v = y + 1; v < mx + 2; v++) {
            s[v]++; // 把 y 加到 cnt 数组中,更新所有受到影响的前缀和
        }
    }
    return ans;
};

rust 解法, 执行用时: 0 ms, 内存消耗: 2.3 MB, 提交时间: 2025-04-14 07:48:56

impl Solution {
    // 暴力枚举
    pub fn count_good_triplets1(arr: Vec<i32>, a: i32, b: i32, c: i32) -> i32 {
        let n = arr.len();
        let mut ans = 0;
        for i in 0..n {
            for j in i + 1..n {
                for k in j + 1..n {
                    if (arr[i] - arr[j]).abs() <= a && (arr[j] - arr[k]).abs() <= b && (arr[i] - arr[k]).abs() <= c {
                        ans += 1;
                    }
                }
            }
        }
        ans
    }
    // 前缀和
    pub fn count_good_triplets(arr: Vec<i32>, a: i32, b: i32, c: i32) -> i32 {
        let mut ans = 0;
        let mx = *arr.iter().max().unwrap();
        let mut s = vec![0; (mx + 2) as usize]; // cnt 数组的前缀和
        for (j, &y) in arr.iter().enumerate() {
            for &z in &arr[j + 1..] {
                if (y - z).abs() > b {
                    continue;
                }
                let l = (y - a).max(z - c).max(0);
                let r = (y + a).min(z + c).min(mx);
                // 如果 l > r + 1,s[r + 1] - s[l] 可能是负数
                ans += 0.max(s[(r + 1) as usize] - s[l as usize]);
            }
            for v in y + 1..mx + 2 {
                s[v as usize] += 1; // 把 y 加到 cnt 数组中,更新所有受到影响的前缀和
            }
        }
        ans
    }
}

python3 解法, 执行用时: 724 ms, 内存消耗: 13.3 MB, 提交时间: 2020-08-16 18:42:53

class Solution:
    def countGoodTriplets(self, arr: List[int], a: int, b: int, c: int) -> int:
        m = 0
        for i in range(len(arr)-2):
            for j in range(i+1, len(arr)-1):
                for k in range(j+1, len(arr)):
                    if abs(arr[i] - arr[j]) <= a and abs(arr[j] - arr[k]) <= b and abs(arr[i] - arr[k]) <= c:
                        m +=1
        return m
            

上一题