zoukankan      html  css  js  c++  java
  • 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;
        }

  • 相关阅读:
    如何根据工单状态判断订单状态
    jquery移除click事件
    mysql字符串相关函数(并与sql server对比)
    bootstrap-table api
    js调用jquery的function函数
    Bootstrap table设置th,td内容水平、垂直居中
    Error:java: 无法访问javax.servlet.Servlet 找不到javax.servlet.Servlet的类文件
    html常用表单元素,按钮
    点击重置按钮,清空表单所有内容
    bootstrap table设置列宽
  • 原文地址:https://www.cnblogs.com/niuyourou/p/13352602.html
Copyright © 2011-2022 走看看