拼多多笔试真题【多多的特殊三元组】

多多的特殊三元组(C++/Py/Java /Js/Go)题解

拼多多技术岗 5月17号笔试 第二题

题目内容

在多多王国的数字世界里,多多和我们遇到了一个有趣的数值问题。给定一个整数数组 numsnumsnums,需要找出所有满足特定条件的特殊三元组。

问题描述:

特殊三元组定义为满足以下条件的三元组 (i,j,k)(i, j, k)(i,j,k): 0≤i<j<k<len(nums)0 ≤ i < j < k < len(nums)0≤i<j<k<len(nums),其中 n=len(nums)n = len(nums)n=len(nums),满足: numsi=numsk=numsj∗2numsi = numsk = numsj * 2numsi=numsk=numsj∗2

由于答案可能非常大,请返回结果对 109+710^9 + 7109+7 取余数后的值。

输入描述

第一行:包含一个整数 TTT,表示测试用例的数量。 每个测试用例的输入如下:

  • 第一行:一个整数 nnn,表示数组 numsnumsnums 的长度(0≤n≤3000000 ≤ n ≤ 3000000≤n≤300000)
  • 第二行:包含 nnn 个整数,表示数组 numsnumsnums 的元素(−1000000000≤numsi≤1000000000-1000000000 ≤ numsi ≤ 1000000000−1000000000≤numsi≤1000000000)

输出描述

对于每个测试用例,输出一个整数,表示满足条件的特殊三元组的数量(对 109+710^9 + 7109+7 取模)。

样例1

输入

复制代码
1
4
0 1 0 0

输出

复制代码
1

样例2

输入

复制代码
1
3
6 3 6

输出

复制代码
1

样例3

输入

复制代码
1
5
8 4 2 8 4

输出

复制代码
2

题解

思路

逻辑分析

  1. 从前往后枚举j, 那么该j可以组成的三元组数量等于j左侧值等于num[j]*2 的数量 * j右侧值等于num[j]*2 的数量
  2. 按照1的逻辑,题目难点主要变成如何快速求出左右侧值=numsj * 2的数量,这部分可以通过使用两个哈希表动态追踪各个值的数量。这部分逻辑可参照下面代码
  3. 代码总体时间复杂度为O(n)

C++

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const long  MOD = 1e9+7;

long solve(int n, vector<long>& nums) {
    // 动态右侧指定数数量
    unordered_map<long, int> rightCount;
    for (auto& num : nums) {
        rightCount[num]++;
    }
    long res = 0;
    // 动态追踪左侧指定数数目
    unordered_map<long, int> leftCount;
    for (auto& num : nums) {
        rightCount[num]--;
        int l = leftCount[2 * num];
        int r = rightCount[2 * num];
        res = (res + (l * r) % MOD) % MOD;
        leftCount[num]++;
    }
    return res;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        vector<long> nums(n);
        for (int i = 0; i < n; i++) {
            cin >> nums[i];
        }
        cout << solve(n, nums) << endl;
    }
}

java

java 复制代码
import java.io.*;
import java.util.*;

public class Main {

    static final long MOD = 1000000007L;

    static long solve(int n, long[] nums) {
        // 动态右侧指定数数量
        HashMap<Long, Integer> rightCount = new HashMap<>();
        for (long num : nums) {
            rightCount.put(num, rightCount.getOrDefault(num, 0) + 1);
        }

        long res = 0;

        // 动态追踪左侧指定数数目
        HashMap<Long, Integer> leftCount = new HashMap<>();

        for (long num : nums) {
            rightCount.put(num, rightCount.get(num) - 1);

            int l = leftCount.getOrDefault(2 * num, 0);
            int r = rightCount.getOrDefault(2 * num, 0);

            res = (res + (long) l * r % MOD) % MOD;

            leftCount.put(num, leftCount.getOrDefault(num, 0) + 1);
        }

        return res;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int T = Integer.parseInt(br.readLine());

        while (T-- > 0) {
            int n = Integer.parseInt(br.readLine());

            String[] strs = br.readLine().split(" ");
            long[] nums = new long[n];

            for (int i = 0; i < n; i++) {
                nums[i] = Long.parseLong(strs[i]);
            }

            System.out.println(solve(n, nums));
        }
    }
}

python

python 复制代码
MOD = 10 ** 9 + 7


def solve(n, nums):
    # 动态右侧指定数数量
    right_count = {}

    for num in nums:
        right_count[num] = right_count.get(num, 0) + 1

    res = 0

    # 动态追踪左侧指定数数目
    left_count = {}

    for num in nums:
        right_count[num] -= 1

        l = left_count.get(2 * num, 0)
        r = right_count.get(2 * num, 0)

        res = (res + l * r) % MOD

        left_count[num] = left_count.get(num, 0) + 1

    return res


T = int(input())

for _ in range(T):
    n = int(input())
    nums = list(map(int, input().split()))
    print(solve(n, nums))

javascript

js 复制代码
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const input = [];

rl.on("line", line => {
    input.push(line);
});

rl.on("close", () => {
    const MOD = 1000000007n;

    function solve(n, nums) {
        // 动态右侧指定数数量
        const rightCount = new Map();

        for (const num of nums) {
            rightCount.set(num, (rightCount.get(num) || 0) + 1);
        }

        let res = 0n;

        // 动态追踪左侧指定数数目
        const leftCount = new Map();

        for (const num of nums) {
            rightCount.set(num, rightCount.get(num) - 1);

            const l = leftCount.get(num * 2) || 0;
            const r = rightCount.get(num * 2) || 0;

            res = (res + BigInt(l) * BigInt(r)) % MOD;

            leftCount.set(num, (leftCount.get(num) || 0) + 1);
        }

        return res;
    }

    let idx = 0;
    const T = parseInt(input[idx++]);

    const ans = [];

    for (let t = 0; t < T; t++) {
        const n = parseInt(input[idx++]);

        const nums = input[idx++].split(" ").map(Number);

        ans.push(solve(n, nums).toString());
    }

    console.log(ans.join("\n"));
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

const MOD int64 = 1000000007

func solve(n int, nums []int64) int64 {
	// 动态右侧指定数数量
	rightCount := make(map[int64]int)

	for _, num := range nums {
		rightCount[num]++
	}

	var res int64 = 0

	// 动态追踪左侧指定数数目
	leftCount := make(map[int64]int)

	for _, num := range nums {
		rightCount[num]--

		l := leftCount[2*num]
		r := rightCount[2*num]

		res = (res + int64(l)*int64(r)%MOD) % MOD

		leftCount[num]++
	}

	return res
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var T int
	fmt.Fscan(in, &T)

	for ; T > 0; T-- {
		var n int
		fmt.Fscan(in, &n)

		nums := make([]int64, n)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &nums[i])
		}

		fmt.Println(solve(n, nums))
	}
}
相关推荐
无限码力6 小时前
拼多多笔试真题-多多的Boss挑战(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多技术岗笔试题目·拼多多机试·pdd笔试真题
无限码力2 天前
拼多多笔试真题-多多捕蝇(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多技术岗笔试题目·拼多多机试·pdd笔试真题
无限码力5 天前
拼多多笔试真题-多多的营救行动(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多笔试题库·拼多多技术岗笔试
无限码力6 天前
拼多多笔试真题-对角线遍历矩阵(C++/Py/Java /Js/Go)
矩阵·拼多多·拼多多笔试真题·拼多多技术岗笔试题目·拼多多机试
27669582921 年前
拼多多小程序 anti_content 分析
java·javascript·python·node·拼多多·anti-content·anti_content
27669582921 年前
拼多多 anti-token unidbg 分析
java·python·go·拼多多·pdd·pxx·anti-token
市象2 年前
独家|安克Temu平台闭店,或遭遇亚马逊“二选一”
亚马逊·temu·拼多多
诗雅颂2 年前
【js逆向学习】某多多anti_content逆向(补环境)
开发语言·javascript·webpack·逆向·拼多多·补环境·anti_content
软件、小程序、网站、脚本开发商2 年前
拼多多商品全流程自动化采集
大数据·金融·自动化·制造·零售·教育电商·拼多多