0
点赞
收藏
分享

微信扫一扫

5.1 贪心算法

南柯Taylor 2022-04-08 阅读 73

贪心算法

  • 最自然智慧的算法
  • 用一种局部最功利的标准,总是做出在当前看来是最好的选择
  • 难点在于证明局部最功利的标准可以得到全局最优解
  • 对于贪心算法的学习主要以增加阅历和经验为主

给定一个由字符串组成的数组strs, 必须把所有的字符串拼接起来,返回所有可能的拼接结果中,字典序最小的结果

需要证明这两个点。太难了,证明麻烦

  1. a b c 表示 3 个字符串,a + b 表示 a 拼接上 b
    若 a + b <= b + c, b + c <= c + b 证明:a + c <= c + a
  2. 数据按照 1 的方式进行排序后得到的字符串是最小的字符串,交换任意两个位置,都会导致字典序变大

    public String minDictStr(List<String> strs) {
        List<String> strs2 = strs.stream()
	        .filter(it -> !"".equals(it))
	        .sorted((a, b) -> (a + b).compareTo(b + a))
	        .collect(Collectors.toList());
        return String.join("", strs2);
    }

    public String minDictStrCompare(List<String> strs) {
        if (strs.size() == 0) {
            return "";
        }
        Stack<String> vals = new Stack<>();
        List<String> res = new ArrayList<>();
        process(strs, vals, res);
        res.sort(String::compareTo);
        return res.get(0);
    }

    private void process(List<String> strs, Stack<String> vals, List<String> res) {
        if (strs.size() == 0) {
            res.add(String.join("", vals));
            return;
        }
        for (int i = 0; i < strs.size(); i++) {
            String str = strs.get(i);
            strs.remove(i);
            vals.add(str);
            process(strs, vals, res);
            strs.add(i, str);
            vals.pop();
        }
    }

    @Test
    public void test1() {
        for (int i = 0; i < 10000; i++) {
            List<String> strs = Reduce.stringList(8, 10);
            List<String> strs1 = new ArrayList<>(strs);
            String r1 = minDictStr(strs);
            String r2 = minDictStrCompare(strs);
            if (!r1.equals(r2)) {
                System.out.println(strs);
                System.out.println(r1);
                System.out.println(r2);
                r1 = minDictStr(strs1);
                r2 = minDictStrCompare(strs1);
                return;
            }
        }
    }
举报

相关推荐

0 条评论