每日一题20220623
- 2022-06-17:给定一个数组arr,含有n个数字,可能有正、有负、有0,
 给定一个正数k。
 返回所有子序列中,累加和最大的前k个子序列累加和。
 假设K不大,怎么算最快?
 来自Amazon。
/**
     * 模型:求前k个前缀和最大的数组
     *
     * @param arr
     * @param k
     * @return
     */
    public static int[] topMaxSum(int[] arr, int k) {
        ArrayList<Integer> allAns = new ArrayList<>();
        process(arr, 0, 0, allAns);
        allAns.sort((a,b)->a.compareTo(b));
        int[] ans = new int[k];
        for (int i = allAns.size() -1,j=0;j<k;i--,j++){
            ans[j] = allAns.get(i);
        }
        return ans;
    }
    /**
     * 模型:递归模型:把数组的各个前缀和记录下来
     *
     * @param arr
     * @param index
     * @param sum
     * @param ans
     */
    public static void process(int[] arr, int index, int sum, ArrayList<Integer> ans) {
        if (index == arr.length) {
            ans.add(sum);
        } else {
            process(arr, index + 1, sum, ans);
            process(arr, index + 1, sum + arr[index], ans);
        }
    }
- 2022-06-15:薯队长最近在参加了一个活动,主办方提供了N个礼物以供挑选,
 每个礼物有一个价值,范围在0 ~ 10^9之间,
 薯队长可以从中挑选k个礼物。
 返回:其中价值最接近的两件礼物之间相差值尽可能大的结果。
 小红书第二题。
薯队长最近在玩一个游戏,这个游戏桌上会有一排不同颜色的方块,
每次薯队长可以选择一个方块,便可以消除这个方块以及和他左右相临的
若干的颜色相同的方块,而每次消除的方块越多,得分越高。
具体来说,桌上有以个方块排成一排 (1 <= N <= 200),
每个方块有一个颜色,用1~N之间的一个整数表示,相同的数宇代表相同的颜色,
每次消除的时候,会把连续的K个相同颜色的方块消除,并得到K*K的分数,
直到所有方块都消除。显然,不同的消除顺序得分不同,薯队长希望您能告诉他,这个游戏最多能得到多少分。
小红书第三题。
————————————————
版权声明:本文为CSDN博主「福大大架构师每日一题」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48502062/article/details/125304986
    /**
     * 模型:二分
     *
     * @param arr
     * @param k
     * @return
     */
    public static int maxNear(int[] arr, int k) {
        if (arr.length < k) {
            return -1;
        }
        Arrays.sort(arr);
        int n = arr.length;
        int l = 0;
        int r = arr[n - 1] - arr[0];
        int m = 0;
        int ans = 0;
        while (l <= r) {
            m = (l + r) / 2;
            if (yeah(arr, k, m)) {
                ans = m;
                l = m + 1;
            } else {
                r = m - 1;
            }
        }
        return ans;
    }
    /**
     * 模型:判断是否合格
     *
     * @param arr
     * @param k
     * @param limit
     * @return
     */
    public static boolean yeah(int[] arr, int k, int limit) {
        int last = arr[0];
        int pick = 1;
        for (int i=1;i<arr.length;i++){
            if (arr[i] -last>=limit){
                pick++;
                last = arr[i];
            }
        }
        return pick>=k;
    }
    
- 2022-06-14:数组的最大与和。
 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1 到 numSlots 。
 你需要把所有 n 个整数分到这些篮子中,且每个篮子 至多 有 2 个整数。一种分配方案的 与和 定义为每个数与它所在篮子编号的 按位与运算 结果之和。
 比方说,将数字 [1, 3] 放入篮子 1 中,[4, 6] 放入篮子 2 中,这个方案的与和为 (1 AND 1) + (3 AND 1) + (4 AND 2) + (6 AND 2) = 1 + 1 + 0 + 2 = 4 。
 请你返回将 nums 中所有数放入 numSlots 个篮子中的最大与和。
 力扣2172。
答案2022-06-14:
km算法。
————————————————
版权声明:本文为CSDN博主「福大大架构师每日一题」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48502062/article/details/125286059
    /**
     * 模型:km模型 最优匹配问题
     *
     * @param arr
     * @param m
     * @return
     */
    public static int maximumANDSum(int[] arr, int m) {
        m <<= 1;
        int[][] graph = new int[m][m];
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0, num = 1; j < m; num++, j += 2) {
                graph[i][j] = arr[i] & num;
                graph[i][j + 1] = arr[i] & num;
            }
        }
        return km(graph);
    }
    /**
     * 模型:km模型
     *
     * @param graph
     * @return
     */
    public static int km(int[][] graph) {
        int N = graph.length;
        int[] match = new int[N];
        int[] lx = new int[N];
        int[] ly = new int[N];
        boolean[] x = new boolean[N];
        boolean[] y = new boolean[N];
        int[] slack = new int[N];
        int invalid = Integer.MAX_VALUE;
        for (int i = 0; i < N; i++) {
            match[i] = -1;
            lx[i] = -invalid;
            for (int j = 0; j < N; j++) {
                lx[i] = Math.max(lx[i], graph[i][j]);
            }
            ly[i] = 0;
        }
        for (int from = 0; from < N; from++) {
            for (int i = 0; i < N; i++) {
                slack[i] = invalid;
            }
            Arrays.fill(x, false);
            Arrays.fill(y, false);
            //判断是否冲突
            while (!dfs(from, x, y, lx, ly, match, slack, graph)) {
                int d = invalid;
                for (int i = 0; i < N; i++) {
                    if (!y[i] && slack[i] < d) {
                        d = slack[i];
                    }
                }
                for (int i = 0; i < N; i++) {
                    if (x[i]) {
                        lx[i] = lx[i] - d;
                    }
                    if (y[i]) {
                        ly[i] = ly[i] + d;
                    }
                }
                Arrays.fill(x, false);
                Arrays.fill(y, false);
            }
        }
        int ans = 0;
        for (int i = 0; i < N; i++) {
            ans += (lx[i] + ly[i]);
        }
        return ans;
    }
    /**
     * 模型:dfs模型。
     *
     * @param from
     * @param x
     * @param y
     * @param lx
     * @param ly
     * @param match 表示连接
     * @param slack 最大值数组
     * @param map   连接点
     * @return
     */
    public static boolean dfs(int from, boolean[] x, boolean[] y, int[] lx, int[] ly, int[] match, int[] slack, int[][] map) {
        int N = map.length;
        x[from] = true;
        for (int to = 0; to < N; to++) {
            if (!y[to]) {
                int d = lx[from] + ly[to] - map[from][to];
                if (d != 0) {
                    slack[to] = Math.min(slack[to], d);
                } else {
                    y[to] = true;
                    if (match[to] == -1 || dfs(match[to], x, y, lx, ly, match, slack, map)) {
                        match[to] = from;
                        return true;
                    }
                }
            }
        }
        return false;
    }
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号