区间统计【美团18.09.06校招笔试】

image

思路:

  1. 简单点的,暴力就完事了,但是会超时
  2. 利用滑动窗口思想,利用List模拟一个窗口,在窗口中利用map存储数字出现的次数,每次窗口移动遍历map判断是否有数出现的次数达到阈值t
//暴力法 只能通过82%
 public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            Map<Integer, Integer> map = new TreeMap<>();
            int res = 0;
            int n = in.nextInt();
            int k = in.nextInt();
            int t = in.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = in.nextInt();
            }
            for (int i = 0, j = i + k - 1; j < n; i++, j++) {
                for (int p = i; p <= j; p++) {
                    if (map.containsKey(arr[p])) {
                        map.put(arr[p], map.get(arr[p]) + 1);
                    } else {
                        map.put(arr[p], 1);
                    }
                }
                if (isT(map, t)) {
                    res++;
                }
                map.clear();
            }
            System.out.println(res);
        }
    }

    private static boolean isT(Map<Integer, Integer> map,int t) {
        for (Integer key : map.keySet()) {
            int value = map.get(key);
            if (value >= t) {
                return true;
            }
        }
        return false;
    }
    
    
//滑动窗口法
public class Main {

    static class Node {
        int index;
        int value;

        Node(int index, int value) {
            this.index = index;
            this.value = value;
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            int k = in.nextInt();
            int t = in.nextInt();

            int[] arr = new int[n];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = in.nextInt();
            }
            //用一个List来模拟窗口
            LinkedList<Node> list = new LinkedList<>();
            //value:times利用map来统计每个value出现的次数
            HashMap<Integer, Integer> map = new HashMap<>();
            int end = 0;
            int res = 0;//统计次数
            while (end < arr.length) {
                if (list.size() < k) {
                    list.add(new Node(end, arr[end]));
                    addNode(map,arr,end);
                    end++;
                }

                if (list.size() == k) {
                    //统计出现的次数有没有大于t
                    int temptimes = 0;
                    for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                        temptimes = Math.max(temptimes, entry.getValue());
                    }
                    if (temptimes >= t) {
                        res++;
                    }
                    
                    //弹出list最前面的值
                    Node node = list.poll();
                    if (map.get(node.value) == 1) {
                        map.remove(node.value);
                    }else {
                        //出现次数-1
                        map.put(node.value, map.get(node.value) - 1);
                    }
                }
            }
            System.out.println(res);
        }
    }

    private static void addNode(HashMap<Integer,Integer> map,int arr[],int end) {
        if (!map.containsKey(arr[end])) {
            map.put(arr[end], 1);
        }else {
            map.put(arr[end], map.get(arr[end])+1);
        }
    }
}
原文地址:https://www.cnblogs.com/keeya/p/9602726.html