leetcode每日一题系列-皇位继承顺序

397 阅读1分钟

leetcode-1600-皇位继承顺序

[博客链接]

一个菜🐔的学习之路

掘金首页

[题目描述]

给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。 

 请返回所有可行解 s 中最长长度。 



 示例 1: 

 输入:arr = ["un","iq","ue"]
输出:4
解释:所有可能的串联组合是 "","un","iq","ue","uniq""ique",最大长度为 4。


 示例 2: 

 输入:arr = ["cha","r","act","ers"]
输出:6
解释:可能的解答有 "chaers""acters"。


 示例 3: 

 输入:arr = ["abcdefghijklmnopqrstuvwxyz"]
输出:26




 提示: 


 1 <= arr.length <= 16 
 1 <= arr[i].length <= 26 
 arr[i] 中只含有小写英文字母 

 Related Topics 位运算 回溯算法 
 👍 110 👎 0

[题目链接]

leetcode题目链接

[github地址]

代码链接

[思路介绍]

思路一:链表存储查找

  • birth(p,c)函数存储当前节点名称、状态、子节点链表,每一次都做一次深度优先遍历查找p节点,然后插入c节点
  • **death(p)**节点相同深度优先所有节点,然乎改变节点状态
  • getInheritanceOrder() 深度优先遍历,根据状态返回字符串
  • TLE了
class ThroneInheritance {

          private String name;

        private boolean status;

        private List<ThroneInheritance> children;

        public ThroneInheritance(String kingName) {
            this.name = kingName;
            this.status = true;
            this.children = new ArrayList<>();
        }

        public void birth(String parentName, String childName) {
            if (parentName.equals(this.name)) {
                this.children.add(new ThroneInheritance(childName));
                return;
            }
            for (ThroneInheritance child : children) {
                if (child.getName().equals(parentName)) {
                    child.getChildren().add(new ThroneInheritance(childName));
                    return;
                }
                child.birth(parentName, childName);

            }
        }

        public void death(String name) {
            if (this.name.equals(name)) {
                this.status = false;
                return;
            }
            for (ThroneInheritance child : this.children
            ) {
                child.death(name);
            }
        }

        public List<String> getInheritanceOrder() {
            List<String> order = new ArrayList<>();
            if (this.status) {
                order.add(this.name);
            }
            for (ThroneInheritance child : this.children) {
                order.addAll(child.getInheritanceOrder());
            }
            return order;
        }

        public String getName() {
            return name;
        }


        public List<ThroneInheritance> getChildren() {
            return children;
        }
}

birth(), death(), getInheritanceOrder()时间复杂度都为O(n),n是节点总数


思路二:hash存储

  • 思路一的时长可优化的点主要在于如何快速找到当前节点
  • hashMap以及hashSet分别记录节点名,和死亡节点
 class ThroneInheritance {

        Map<String, List<String>> map = new HashMap<>();

        Set<String> deathSet = new HashSet<>();

        private String name;


        public ThroneInheritance(String kingName) {
            this.name = kingName;
            this.map = new HashMap<>();
        }

       
        //优化:可以通过map来存储父子关系,set来存储所有死亡节点
        //定义一个map,key为名字,value为子数组,查找为O(1)
        public void birth(String parentName, String childName) {
            List<String> children = this.map.getOrDefault(parentName, new ArrayList<>());
            children.add(childName);
            map.put(parentName, children);
        }
        //优化map存储,快速存取死亡状态
        public void death(String name) {
            deathSet.add(name);
        }

        public List<String> getInheritanceOrder() {
            List<String> res = new ArrayList<String>();
            pre(res, this.name);
            return res;
        }

        //前序遍历
        public void pre(List<String> res, String name) {
            if (!deathSet.contains(name)) {
                res.add(name);
            }
            List<String> children = this.map.getOrDefault(name, new ArrayList<String>());
            for (String childName : children) {
                pre(res, childName);
            }
        }

    }

时间复杂度death(), birth()均为O(1),getInheritanceOrder()为O(n)