首页 > 试题广场 >

用户喜好

[编程题]用户喜好
  • 热度指数:6711 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

为了不断优化推荐效果,今日头条每天要存储和处理海量数据。假设有这样一种场景:我们对用户按照它们的注册时间先后来标号,对于一类文章,每个用户都有不同的喜好值,我们会想知道某一段时间内注册的用户(标号相连的一批用户)中,有多少用户对这类文章喜好值为k。因为一些特殊的原因,不会出现一个查询的用户区间完全覆盖另一个查询的用户区间(不存在L1<=L2<=R2<=R1)。



输入描述:
输入: 第1行为n代表用户的个数 第2行为n个整数,第i个代表用户标号为i的用户对某类文章的喜好度 第3行为一个正整数q代表查询的组数  第4行到第(3+q)行,每行包含3个整数l,r,k代表一组查询,即标号为l<=i<=r的用户中对这类文章喜好值为k的用户的个数。 数据范围n <= 300000,q<=300000 k是整型


输出描述:
输出:一共q行,每行一个整数代表喜好值为k的用户的个数
示例1

输入

5
1 2 3 3 5
3
1 2 1
2 4 5
3 5 3

输出

1
0
2

说明

样例解释:
有5个用户,喜好值为分别为1、2、3、3、5,
第一组询问对于标号[1,2]的用户喜好值为1的用户的个数是1
第二组询问对于标号[2,4]的用户喜好值为5的用户的个数是0
第三组询问对于标号[3,5]的用户喜好值为3的用户的个数是2
// 亲测可用 
let print = (_favo, _queryLRK) => {
  for (let i=0; i<_queryLRK.length; i++) {
    let [l, r, k] = _queryLRK[i];
    let fk = _favo[k];
    let count = 0;
    if (fk === undefined) {
      console.log(0);
    } else {
      for (let j=0; j<fk.length; j++) {
        if (l <= fk[j] && fk[j] <= r) {
          count ++;
        }
      }
      console.log(count);
    }
  }
}

let readline = require('readline');
let rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
let n;
let count = 0;
let favo = {};
let q;
let queryLRK = [];
rl.on('line', (line) => {
  let tokens = line.split(' ');
  if (count === 0) {
    n = parseInt(tokens[0]);
  } else if (count === 1) {
    for (let i=0; i<n; i++) {
      if (favo[tokens[i]] === undefined) {
        favo[tokens[i]] = [];
      }
      favo[tokens[i]].push(i+1);
    }
  } else if (count === 2) {
    q = parseInt(tokens[0]);
  } else {
    queryLRK.push(tokens);
    q--;
    if (q === 0) {
      print(favo, queryLRK);
      rl.close();
    }
  }
  count < 3 && count++;
});


发表于 2018-09-08 16:43:08 回复(2)
import java.util.*;
 
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        HashMap<Integer,ArrayList<Integer>> map = new HashMap<>();
        for(int i=0;i<n;i++){
            int like=sc.nextInt();
            if(map.containsKey(like)){
                map.get(like).add(i+1);
            }else{
                ArrayList<Integer> users = new ArrayList<>();
                users.add(i+1);
                map.put(like,users);
            }
        }
        int m = sc.nextInt();
        while(m>0){
            int left=sc.nextInt();
            int right=sc.nextInt();
            int k=sc.nextInt();
            int res = 0;
            if(map.containsKey(k)){
                ArrayList<Integer> list = map.get(k);
                for(int i=0;i<list.size();i++){
                    if(list.get(i)>=left&&list.get(i)<=right){
                        res++;
                    }
                }
            }
            System.out.println(res);
            m--;
        }
    }
}

发表于 2020-09-12 17:11:45 回复(0)
补记一下这个题目 首先看到的就是数据范围 这么大的数据范围的区间查询 肯定需要nlogn的
时间复杂度来完成 将所有数值按照数的值将下标顺序的存储在vector里面 按照输入的k值查找
到相应的vector 再在这个vector里面对l和r进行二分查找得到具体答案值


#include <bits/stdc++.h>

using namespace std;
const int maxn = 3e5 + 10;
struct node {
    int val;
    int idx;
}a[maxn];
bool cmp(node x,node y)
{
    if(x.val != y.val)
        return x.val < y.val;
    return x.idx < y.idx;
}
vector<int> tmp[maxn];

int tot = 0,f[maxn];

int main()
{
    int n;scanf("%d",&n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d",&a[i].val);
        a[i].idx = i;
    }
    sort(a + 1,a + 1 + n,cmp);
    for(int i = 1; i <= n; i++)
    {
        int j = i;
        f[++tot] = a[i].val;
        while(a[j].val == a[i].val && j <= n)
        {
            tmp[tot].push_back(a[j].idx);
            j++;
        }
        i = j - 1;
    }
    int q;
    cin>>q;
    //for(int i = 1; i <= tot; i++) printf("%d ",f[i]);
    //puts("");
    //puts("");
    while(q--)
    {
        int l,r,k;
        scanf("%d%d%d",&l,&r,&k);
        int pos = lower_bound(f + 1,f + tot + 1,k) - (f);
        //printf("%d %d \n",pos,f[pos]);
        if(f[pos] != k)
        {
            puts("0");continue;
        }
        else
        {
            //printf(" r = %d\n",upper_bound(tmp[pos].begin(),tmp[pos].end(),r) - tmp[pos].begin());
            int r1 = upper_bound(tmp[pos].begin(),tmp[pos].end(),r) - tmp[pos].begin();
            int l1 = lower_bound(tmp[pos].begin(),tmp[pos].end(),l) - tmp[pos].begin();
            printf("%d\n",r1 - l1);
            //printf("l = %d r = %d\n",l1,r1);
            //printf(" l = %d\n",upper_bound(tmp[pos].begin(),tmp[pos].end(),l) - tmp[pos].begin());
        }
    }
    return 0;
}

发表于 2020-03-18 10:29:49 回复(0)

//javascript  借助hashmap先把k值相同的用户序号用数组存起来,然后根据k值找到该数组,
//然后遍历该数组,不用二分法这道题可以过。进一步优化的话可以对数组排序然后使用二分法查找。
let readline = require('readline')
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
})
let n = -3
let k = 0
let like = []
let q = 0
let query = []
let ans = []
rl.on('line', function(line){
    if (n === -3) {
        k = parseInt(line.trim())
        n++
    } else if (n === -2) {
        like = line.trim().split(' ').map(item => parseInt(item))
        n++
    } else if (n === -1) {
        q = parseInt(line.trim())
        n++
    } else {
        query.push(line.trim().split(' ').map(item => parseInt(item)))
        n++
    }
    if (n === q) {
        ans = userlike(like, q, query)
        for (let i = 0; i < ans.length; i++) {
            console.log(ans[i])
        }
        n = -3
        k = 0
        like = []
        q = 0
        query = []
        ans = []
    }
})

function userlike(like, q, query) {
    let ans = []
    let l = 0
    let r = 0
    let k = 0
    let hash = {}
    for (let i = 0, len = like.length; i < len; i++) {
        if (!hash[like[i]]) {
            hash[like[i]] = [i]
        } else {
            hash[like[i]].push(i)
        }
    }
    for (let i = 0; i < q; i++) {
        l = query[i][0]-1
        r = query[i][1]-1
        k = query[i][2]
        ans[i] = 0
        if (hash[k]) {
            let temp = hash[k]
            for (let j = 0; j < temp.length; j++) {
                if (temp[j] >= l && temp[j] <= r) {
                    ans[i]++
                }
            }
        }
    }
    return ans
}


编辑于 2019-08-25 15:25:30 回复(0)
简单粗暴-,- 直接ac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h>
intmain()
{
    intn,q;
    scanf("%d",&n);
    inta[n];
    for(inti=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    scanf("%d",&q);
    intb[q][3];
    for(inti=0;i<q;i++){
        scanf("%d",&b[i][0]);
        scanf("%d",&b[i][1]);
        scanf("%d",&b[i][2]);
    }
    for(inti=0;i<q-1;i++){
        intcount=0;
        for(intj=b[i][0]-1;j<=b[i][1]-1;j++){
            if(b[i][2]==a[j]) count++;
        }
        printf("%d\n",count);
    }
    intcount=0;
    for(inti=b[q-1][0]-1;i<=b[q-1][1]-1;i++){
        if(b[q-1][2]==a[i]) count++;
    }
    printf("%d",count);
}

发表于 2019-03-17 22:20:17 回复(1)
这个题的主要问题就是使用顺序扫描用户的时候会花费比较长的时间,从而导致超时

为了节省顺序查找的时间,我们可以利用二分查找的思路来实现:
1.使用ArrrayList将喜好值相同的用户id存储起来(此时这个ArrayList的用户id是递增的)
2.使用hashmap将该喜好值为k和对应的用户id的list进行存储
3.每次查找时找到对应k的ArrayList进行二分查找即可
最后可以通过所有测试用例

import java.util.*;
public class Main{
    public int getCount(List<Integer> data, int target){
        int left=0, right = data.size()-1, middle=0;
        while(left <= right){
            middle = left + (right-left)/2;
            if (data.get(middle) > target)
                right = middle-1;
            else if(data.get(middle) < target)
                left = middle+1;
            else
                return middle;
        }
        return left;
    }
     
    public void f(){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextLine()){
            int n, q, l, r, k;
            n = Integer.parseInt(sc.nextLine());
            Map<Integer, List<Integer>> map = new HashMap<>();
            for(int i=1; i<=n; i++) {
                int worth = sc.nextInt();
                if(!map.containsKey(worth))
                    map.put(worth, new ArrayList<>());
                map.get(worth).add(i);
            }
            sc.nextLine();
            q = Integer.parseInt(sc.nextLine());
            for(int i=0; i<q; i++){
                l = sc.nextInt();
                r = sc.nextInt();
                k = sc.nextInt();
                sc.nextLine();
                if(map.containsKey(k)){
                    if(r<map.get(k).get(0) || l > map.get(k).get(map.get(k).size() -1))
                        System.out.println(0);
                    else{
                        int left = getCount(map.get(k), l);
                        int right = getCount(map.get(k), r);
                        if (right < map.get(k).size() && map.get(k).get(right) == r)
                            System.out.println(right-left+1);
                        else
                            System.out.println(right - left);
                    }
                }else
                    System.out.println(0);
            }
        }
    }
     
    public static void main(String[] args){
        new Main().f();
    }
}

编辑于 2018-09-10 10:27:40 回复(2)
//给前面的回答添加了点注释,方便阅读
let chaxunzuarr = [];
//第一行输入,用户个数
let yonghushu = readline(),
    //第二行输入,用户对应喜好,转化为数组
    xihaoduarr = readline().split(' '),
    //第三行输入,查询组数
    chaxunzushu = readline();
//循环所有查询组,4行开始的所有行
for(let i = 0;i<chaxunzushu;i++){
    //取得每行值,转为数组
    chaxunzuarr[i] = readline().split(' ');
}
let arr = [];
//遍历喜好度数组,将相同喜好度的下标添加进一个新数组
//样例添加完后生成arr=[,[0],[1],[2,3],,[4]]
xihaoduarr.forEach((item,index) => {
    if(arr[item] == undefined){
        arr[item] = [];
    }
    arr[item].push(index);
});

//遍历查询组
for(let j = 0;j<chaxunzushu;j++){
    //取得每行第一个数l,转化为下标-1
    let start = chaxunzuarr[j][0] - 1,
    //取得每行第二个数r,转化为下标-1
    end = chaxunzuarr[j][1] - 1,
    //取得每行第三个数k,喜好度
    value = chaxunzuarr[j][2],
    //初始化结果用户个数
    geshu = 0;
    if(arr[value] == undefined){
        //下标数组为未定义时,无喜好度
        console.log(0);
    }else{
        //循环下标数组内元素,判断元素数组内元素是否处于标号间
        arr[value].forEach(e=>{
            if(e>=start && e<=end){
                geshu++;
            }
        })
        print(geshu);
    }
}

发表于 2019-05-16 09:51:44 回复(8)
牛客网对js代码测试充满了深深地恶意。
function res(people,likesArr,q,selectObj){  for(let i = 0; i < q; i++){  let bef = selectObj[i][0];// 1 2 1    let aft = selectObj[i][1];// 2    let c = selectObj[i][2];    let com = likesArr.slice(bef-1, aft-1);    let num = 0;    if(com.length > 0){  for(let j = 0; j < com.length; j++){
      if(com[j] === c){
                 num++;    }
            }
        }
        console.log(num);    }
} res(5,[1,2,3,3,5],3,[[1,2,1],[2,4,5],[3,5,3]]);

发表于 2019-07-25 12:22:29 回复(2)
不吹不黑,这题我做了至少5个小时。
JS代码如下:
let chaxunzuarr = [];
let yonghushu = readline(),
    xihaoduarr = readline().split(' '),
    chaxunzushu = readline();
for(let i = 0;i<chaxunzushu;i++){
    chaxunzuarr[i] = readline().split(' ');
}

let arr = [];
xihaoduarr.forEach((item,index) => {
    if(arr[item] == undefined){
        arr[item] = [];
    }
    arr[item].push(index);
});
for(let j = 0;j<chaxunzushu;j++){
    let start = chaxunzuarr[j][0] - 1,
    end = chaxunzuarr[j][1] - 1,
    value = chaxunzuarr[j][2],
    geshu = 0;
    if(arr[value] == undefined){
        console.log(0);
    }else{
        arr[value].forEach(e=>{
            if(e>=start && e<=end){
                geshu++;
            }
        })
        print(geshu);
    }
}

发表于 2019-04-21 15:31:49 回复(2)
n = int(input())
arr = list(map(int,input().split(' ')))
dic = {}
index = 1
for i in arr:
    if i not in dic:
        dic[i] = [index]
    else:
        dic[i].append(index)
    index += 1
m = int(input())
for k in range(m):
    [s,e,i] = list(map(int,input().split(' ')))
    total = 0
    arr = dic[i]
    for x in arr:
        if x >= s and x <= e:
            total += 1
        if x > e:
            break
    print(total)



var n = readline()
var arr = readline().split(' ')
var dic = new Array()
var index = 1
for(var i of arr){
    if(dic[i] == null){
        dic[i] = [index]
    }else{
        dic[i].push(index)
    }
    index ++
}
var m = readline()
while(m--){
    [s,e,i] = readline().split(' ')
    sum = 0
    arr = dic[i]
    for(var x of arr){
        if(x >= s && x <= e){
            sum ++
        }
        if(x > e){
            break
        }
    }
    console.log(sum)
}

我真的是无力吐槽牛客网这个垃圾编译器,leetcode上面真的是好太多了,不是各个公司没事就在这笔试,我是真的一万个不愿意在这上面刷题。
上面两个代码,除了语言不一样,没有一丝一毫的差别。我都尽量把变量都控制的一模一样了。
python过了0%,js过了70%。简直是呵呵


发表于 2019-03-19 13:28:18 回复(1)
#include <iostream>;
usingnamespacestd;
intmain() {
    int a[300000] , user = 0, i = 0,search = 0,b, c, d,number;
    cin >> user;//用户输入
    for(i = 1; i <=user; i++) {
        cin >> a[i];//用户喜好度输入
    }
    cin >> search;//查找数组个数
    while(search--&& cin >> b >> c >> d){ //输入查找数组位置和信息
        number = 0;
        for(i = b; i <=c; i++){
            if(a[i]==d) {
                number++;//人数统计
             }
        }
        cout << number << endl;
    }
}
发表于 2021-08-06 22:16:10 回复(0)
使用Map保存喜好度相同的用户,通过全部测试用例
#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
int main(){
    int n = 0;
    cin>>n;
    unordered_map<int,vector<int>> fav_users;
    for(int i = 0;i<n;i++){
        int fav = 0;
        cin>>fav;
        if(fav_users.count(fav)){
            fav_users[fav].push_back(i+1);
        }else{
            fav_users[fav] = {i+1};
        }
    }
    int rows = 0;
    cin>>rows;
    vector<int> result(rows);
    for(int i = 0;i<rows;i++){
        int start = 0, end = 0, fav = 0, count = 0;
        cin>>start>>end>>fav;
        for(int x:fav_users[fav]){
            if(x>=start && x<=end) count++;
            if(x>end)break;
        }
        result[i] = count;
    }
    for(int x:result){
        cout<<x<<endl;
    }
    return 0;
}

发表于 2019-03-14 11:31:46 回复(0)
使用简单的顺序扫描,之前没通过是因为使用指针后没有释放,在return前释放即可
#include <iostream>
using namespace std;
int main() {
    int n, q;
    cin>>n;
    int* favor = new int[n];
    for(int i = 0; i < n; i++) {
        cin>>favor[i];
    }
    cin>>q;
    int** query = new int*[q];
    for(int i = 0; i < q; i++) {
        query[i] = new int[3];
        for(int j = 0; j < 3; j++) {
            cin>>query[i][j];
        }
    }
    for(int i = 0; i < q; i++) {
        int count = 0;
        for(int  j = query[i][0]-1; j < query[i][1]; j++) {
            if(favor[j] == query[i][2]) {
                count++;
            }
        }
        cout<<count<<endl;
    }
    delete []favor;
    for(int i = 0; i < q; i++) {
        delete []query[i];
    }
    return 0;
}

编辑于 2018-09-30 23:28:54 回复(0)

C++, 使用哈希表记录每个喜好值对应的下标集合,然后二分查找。

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n, like;; cin >> n;
    unordered_map<int, vector<int>> mp;
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &like);
        mp[like].push_back(i);
    }
    int q, left, right; cin >> q;
    while (q--) {
        scanf("%d%d%d", &left, &right, &like);
        auto it1 = lower_bound(mp[like].begin(), mp[like].end(), left);
        auto it2 = upper_bound(mp[like].begin(), mp[like].end(), right);
        cout << (it2 - it1) << endl;
    }
    return 0;
}
发表于 2023-02-12 14:52:14 回复(0)
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void async function () {
    // Write your code here
    let idx = 0;
    let userStar = {};
    while(line = await readline()){
        let tokens = line.split(' ');
        if (idx === 1) {
            userStar = tokens.reduce((pre, cur, idx) => {
                if (pre[cur]) {
                    pre[cur].push(idx)
                    return pre;
                };
                pre[cur] = [idx];
                return pre; 
            }, {});
        }
        if (idx > 2) {
            const start = parseInt(tokens[0]) - 1;
            const end = parseInt(tokens[1]) - 1;
            const starList = userStar[tokens[2]] ?? [];
            console.log(starList.filter(v => v >= start && v <= end).length)
        }
        idx++
    }
}()


发表于 2023-07-10 20:59:45 回复(0)
自测怎么测都对,用例一个没通过,为什么?求大佬教我
let usernum=readline();
let user=readline().split('')
var arr=[]
for(var i=0;i<=user.length;i++){
    if(i%2==0){
        arr.push(user[i])
    }else{
        continue
    }
}
let q=readline()
var fun=function(s,f,k){
    let num=0;
    for(var i=s-1;i<f;i++){
        if(arr[i]==k){
            num++;
            continue
        }else{
            continue
        }
    }
    print(num)
}
while(lines=readline()){
    var liness = lines.split('');
    var s = parseInt(liness[0]);
    var f = parseInt(liness[2]);
    var k = parseInt(liness[4]);
    fun(s,f,k);
}


发表于 2022-10-08 14:14:14 回复(0)
let l1=readline();
let n1=parseInt(l1);
let l2=readline();
let yhxh=l2.split(' ').map((i)=>parseInt(i));
let yhxharr=[];
yhxh.forEach((item,i)=>{
    if(yhxharr[item]==undefined) yhxharr[item]=[];
     yhxharr[item].push(i);
})
let l3=readline();
let n3=parseInt(l3);//测试数据个数
for(let i=0;i<n3;i++){
    let lines=readline();
    let cesz=lines.split(' ').map((i)=>parseInt(i));
    let l=cesz[0]-1;
    let r=cesz[1]-1;
    let k=cesz[2];
    let cnt=0;
    if(yhxharr[k]==undefined) print(0);
    else{
        yhxharr[k].forEach((item,i)=>{
            if(item>=l&&item<=r) cnt++;
        })
        print(cnt);
    }
}

发表于 2022-07-26 13:42:22 回复(1)
/**
 * 不知道哪个活雷锋在第15个测试用例里给了个不存在的k,真的是吃了屎。直接到find函数里面加上一个判断吧
 * 如果用传统的线性查找的方法应该会超时
 * 提高速度,可以用hashmap的查找和二分查找,能用二分查找是因为id是递增有序的
 * 把具有相同k值的用户编号用arraylist存储,k和arraylist构成hashmap,
 * 这样一来,k值的查询可以用O(1)的时间
 * 然后获得具有相同k值的用户id列表,用二分查找,注意查找的时候是分左右边界的,给我的l和r不一定在列表里面
 * 如果找不到l,那就返回l后面一个,如果找不到r,就返回r前面一个,做个差就是在[l,r]内的个数了
 */

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException{
        List<Integer> likes = new ArrayList<>();
        HashMap<Integer,List<Integer>> k_to_likes = new HashMap<>();
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            likes.add(sc.nextInt());
            int index = likes.get(i);
            if (! k_to_likes.containsKey(index)){
                List<Integer> item = new ArrayList<>();
                k_to_likes.put(index, item);
            }
            k_to_likes.get(index).add(i+1);
        }

        int p = sc.nextInt();

        for (int i = 0; i < p; i++) {
            int l = sc.nextInt();
            int r = sc.nextInt();
            int k = sc.nextInt();
            find(k_to_likes, l, r, k);
        }
//        while (sc.hasNextInt() && )
    }
    public static void find(HashMap<Integer,List<Integer>> k_to_likes, int l, int r, int k) throws IOException {
        if (! k_to_likes.containsKey(k)) {
            System.out.println(0);
            return;
        }
        List<Integer> sanme_like = k_to_likes.get(k);
        int count = binary_seatch(sanme_like,r,"right")-binary_seatch(sanme_like,l,"left") + 1;
        System.out.println(count);
    }
    public static int binary_seatch(List<Integer> sanme_like, int target, String position) throws IOException{
        if (sanme_like.isEmpty()) return 0;
        int left = 0, right = sanme_like.size() -1;
        while (left <= right) {
            int mid = left + (right-left)/2;
            if (sanme_like.get(mid) == target) return mid;
            else if (sanme_like.get(mid) > target) {
                right = mid - 1;
            }
            else if (sanme_like.get(mid) < target) {
                left = mid + 1;
            }
        }
        return position.equals("left") ? left : right;
    }

}

编辑于 2022-05-14 14:50:33 回复(0)
let readline = require('readline');
let lines = 1;
let n;
let arr = []
let favo = {}
let t;
let query = []
// var k=2; //这里代表题目中设定好的输入的行数
let rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
rl.on('line', (line) => {
  if (lines === 1) {
    n = line-0;
  }
  if (lines === 2) {
    arr = line.split(' ')

    for (let i = 0; i < n; i++){
      if (!favo[arr[i]]) {
        favo[arr[i]] =[]
      }
      favo[arr[i]].push(i+1)
    }
  }
  else if (lines === 3) {
    t = line - 0;
  } else if(lines>3){
    query.push(line.split(' '));
    if (query.length === t) {

      request(favo,query);
      rl.close();
    }
  }
  lines++;
})
function request(_favo, _query) {
  
  for (let i = 0; i < _query.length; i++) {

    let [l, r, k] = _query[i];
    

    let count = 0;
    if (!_favo[k]) {
      // console.log(_favo[k])
      console.log(0);
    } else {
      for (let j = 0; j < _favo[k].length; j++){
        if (favo[k][j] >= l && favo[k][j] <= r )
          count++;
      }
      console.log(count);
    }
  }
}

发表于 2022-05-04 19:23:58 回复(0)
参考二楼老哥的思路,贴一下js版的题解:
const n = readline();
const preferArr = readline().split(' ').map(item => parseInt(item)); // 喜好数组
preferArr.unshift(-1); // 在数组头部插入一个元素,对其下标
const amount = parseInt(readline()); // 查询数组
const hash = new Map();
// 构造哈希表
preferArr.forEach((item, index) => {
    if (!hash.has(item)) {
        hash.set(item, [index])
    } else {
        const temp = hash.get(item);
        temp.push(index);
        hash.set(item, temp);
    }
})

for (let i = 0; i < amount; i++) {
    let cnt = 0;
    const data = readline().split(' ').map(item => parseInt(item));
    const l = data[0];
    const r = data[1];
    const k = data[2];
    
    if (hash.has(k)) {
    const idList = hash.get(k);
    if (r < idList[0] || l > idList[idList.length - 1]) {
        console.log(cnt);
    } else {
        // 二分查找获取哈希表对应项中的下标
        const left = getIndex(idList, l);
        const right = getIndex(idList, r);
        console.log(left, right);
        if (right < idList.length && idList[right] === r) {
            console.log(right - left + 1);
        } else {
            console.log(right - left);
        }
    }
    } else {
        console.log(0);
    }
}

function getIndex(arr, target) {
    let l = 0, r = arr.length - 1;
    while (l <= r) {
        let mid = Math.floor((l + r) / 2);
        if (arr[mid] === target) {
            return mid;
        } else if (arr[mid] < target) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return l;
}



发表于 2022-03-10 18:33:29 回复(0)