• Leetcode 1405 最长快乐字符串 穷举与贪心


     

      题目被 leetcode 归类为动态规划,苦思冥想,没有找到合适的问题定义。

      决定首先穷举,借以理解解空间的结构。穷举解法:

    /**
         * @Author Niuxy
         * @Date 2020/7/20 11:17 下午
         * @Description 穷举
         */
        String longestStr = "";
    
        public String longestDiverseString(int a, int b, int c) {
            longest(a, b, c, "");
            return longestStr;
        }
    
        public final void longest(int a, int b, int c, String s) {
            longestStr = s.length() > longestStr.length() ? s : longestStr;
            if (a == 0 && b == 0 && c == 0) {
                return;
            }
            if (a > 0 && canInsert('a', s)) {
                longest(a - 1, b, c, s + "a");
            }
            if (b > 0 && canInsert('b', s)) {
                longest(a, b - 1, c, s + "b");
            }
            if (c > 0 && canInsert('c', s)) {
                longest(a, b, c - 1, s + "c");
            }
        }
    
        private final boolean canInsert(char ch, String s) {
            int length = s.length();
            if (length < 2) {
                return true;
            }
            char char0;
            if ((char0 = s.charAt(length - 1)) == s.charAt(length - 2)) {
                if (char0 == ch) {
                    return false;
                }
            }
            return true;
        }

      穷举函数就像一把散弹枪,在每个节点将所有可能性散射出去。直到三个元素都用完或者不可继续拼接,将结果数组进行记录,取全局最大值。

        明显的,要从所有可能的组合中找最长的组合,问题的定义没有最优子结构性质。

      D(a,b,c) 的定义不能是返回最长序列,上层问题无法根据该结果得出上层问题的最优解。

      D(a,b,c) 的定义只能是尝试所有可能的路径,上层问题基于该结果拓展出本层的所有可能的路径,从中取最优值。

        穷举路径进行搜索的函数没有建立缓存的必要,因为每条路径只会尝试一次。

          这样避免重复计算的路就行不通了。

      只能从另一个方向,避免无效计算来提升效率。

      凭直觉,想要结果字符串最长,应该最先将存量最多的元素拼入字符串,用次多的元素分割最多的元素。

      因为剩余元素中最多的元素越少,剩余元素可以组成的字符串也越长。

      贪心解法:

        class CharAndNum implements Comparable {
            char ch;
            int count;
    
            CharAndNum(char ch, int count) {
                this.ch = ch;
                this.count = count;
            }
    
            @Override
            public int compareTo(Object o) {
                CharAndNum other = (CharAndNum) o;
                return other.count-count;
            }
        }
    
        public String longestDiverseString1(int a, int b, int c) {
            CharAndNum[] chars = new CharAndNum[]{
                    new CharAndNum('a', a),
                    new CharAndNum('b', b),
                    new CharAndNum('c', c)
            };
            StringBuilder sb = new StringBuilder();
            while (true) {
                System.out.println(sb.toString());
                Arrays.sort(chars);
                if (isEnd(chars, sb)) {
                    break;
                }
                if (canInsert(sb, chars[0].ch)) {
                    sb.append(chars[0].ch);
                    chars[0].count--;
                } else if (chars[1].count > 0) {
                    sb.append(chars[1].ch);
                    chars[1].count--;
                }
            }
            return sb.toString();
        }
    
        private final boolean isEnd(CharAndNum[] chars, StringBuilder sb) {
            if (chars[0].count == 0) {
                return true;
            }
            if (!canInsert(sb, chars[0].ch)) {
                if (chars[1].count == 0) {
                    return true;
                }
            }
            return false;
        }
    
        private boolean canInsert(StringBuilder sb, char ch) {
            int length = sb.length();
            if (length < 2) {
                return true;
            }
            char pre;
            if ((pre = sb.charAt(length - 1)) == sb.charAt(length - 2)) {
                if (pre == ch) {
                    return false;
                }
            }
            return true;
        }

  • 相关阅读:
    教练技术的小应用
    “货品未动,数据先行”,德邦快递与网易云联合打造“智能物流”
    小论数据分析的方法及思维
    网易蜂巢(云计算基础服务)MongoDB服务重磅来袭
    pdfjs viewer 开发小结
    wap html5播放器和直播开发小结
    MongoDB之我是怎么成为Primary节点的
    MongoDB中WiredTiger的数据可用性设置
    AutoMapper 自动映射工具
    linq 左连接实现两个集合的合并
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13352602.html
Copyright © 2020-2023  润新知