0
点赞
收藏
分享

微信扫一扫

拿捏---JVM原理

进击的铁雾 2023-11-24 阅读 57

题目

思路

以单组数据来看,对于给定数组nums,是否存在连续和能够被指定k整除?可以想到一下几种方案:

  1. 暴力破解
  2. 组合思想
  3. 前缀和

思路一:暴力破解

思路二:组合思想

思路三:前缀和
参考leetcode原题:974. 和可被 K 整除的子数组
leetcode的题目考虑了负数,虽然本题的牌的数字不会有正数,但这里还是对正负数都考虑进来。

题解

给出了三种思路在本题的具体实现,前缀和确实很抽象,也不好表达,对此不理解的多看看974. 和可被 K 整除的子数组的题解

package hwod;

import java.util.*;
import java.util.stream.Collectors;

public class NumberGame {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> list1 = new ArrayList<>();//存放给定的牌
        List<List<Integer>> list2 = new ArrayList<>();//牌堆
        while (sc.hasNextLine()) {
            String firstLines = sc.nextLine();
            if ("".equals(firstLines)) break;
            list1.add(Arrays.stream(firstLines.split(" ")).mapToInt(Integer::parseInt).toArray()[1]);
            String secondLines = sc.nextLine();
            list2.add(Arrays.stream(secondLines.split(" ")).mapToInt(Integer::parseInt).boxed().collect(Collectors.toList()));
        }
        List<Integer> res = numberGame(list1, list2);
        for (Integer re : res) {
            System.out.println(re);
        }
    }

    private static List<Integer> numberGame(List<Integer> list1, List<List<Integer>> list2) {
        List<Integer> res = new ArrayList<>();
        for (int i = 0; i < list1.size(); i++) {
            res.add(checked3(list2.get(i), list1.get(i)));
        }
        return res;
    }

    /**
     * 暴力破解
     * @param list   牌堆
     * @param target 被除的值
     * @return 如果存在连续和能够整除target,返回1,否则返回0
     */
    private static int checked(List<Integer> list, Integer target) {
        for (int i = 0; i < list.size(); i++) {
            int sum = 0;
            for (int j = i; j < list.size(); j++) {
                sum += list.get(j);
                if (sum % target == 0) return 1;
            }
        }
        return 0;
    }

    private static int res = 0;

    /**
     * 组合思想
     * @param list
     * @param target
     * @return
     */
    private static int checked2(List<Integer> list, Integer target) {
        LinkedList<Integer> path = new LinkedList<>();
        dfs(list, 0, path, 0, target);
        return res;
    }

    private static void dfs(List<Integer> list, int start, LinkedList<Integer> path, int sum, int k) {
        if (!path.isEmpty() && sum % k == 0) {
            res = 1;
            return;
        }
        for (int i = start; i < list.size(); i++) {
            if (!path.isEmpty() && path.peekLast() != i - 1) continue;
            if (res != 0) break;
            path.addLast(i);
            dfs(list, i + 1, path, sum + list.get(i), k);
            path.removeLast();
        }
    }

    /**
     * 设P[i]为前i项的前缀和
     * sum(i,j)=num[i]+num[i+1]+...+num[j]=P[j]-p[i-1]
     * (P[j]-p[i])%k==0  ==>  (P[j]%k - p[i-1]%k)%k=0
     *
     * @param list
     * @param k
     * @return 如果存在连续和能够整除k,返回1,否则返回0
     */
    private static int checked3(List<Integer> list, Integer k) {
        int[] dp = new int[k];
        dp[0] = 1;
        int sum = 0;
        for (int i = 0; i < list.size(); i++) {
            sum += list.get(i);
            int mod = (sum % k + k) % k;
            if (dp[mod] != 0) return 1;
            dp[mod]++;
        }
        return 0;
    }
}


推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

举报

相关推荐

0 条评论