leetCode进阶算法题+解析(二十二)

二叉树的前序遍历

题目:给定一个二叉树,返回它的 前序 遍历。
题目截图

思路:这个题也没啥思路可说的,一个递归一个迭代,我都写一遍就行了。然后之前做过一个中序排列。刚刚还看到下一道题是后续排列。一起做了得了,我去写代码了。
首先是递归实现:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<Integer> res;
    public List<Integer> preorderTraversal(TreeNode root) {
        res = new ArrayList<Integer>();
        pre(root);
        return res;
    }
    public void pre(TreeNode root){
        if(root==null) return;
        res.add(root.val);
        pre(root.left);
        pre(root.right);
    }
}

迭代实现:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if(root == null) return res;
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while(root!=null || !stack.isEmpty()){
            if(root!=null){
                res.add(root.val);
                if(root.left != null)stack.push(root.left);
                root = root.left;
            }else{                
                root =  stack.pop();                
                if(root.right != null)stack.push(root.right);
                root = root.right;
            }
        }
        return res;
    }
}

不得不说反正我这两个代码还是递归性能比较高。不过我看了人家的迭代实现,比我要好看多了。。。我直接贴代码了:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        if(root == null) return res;
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
        stack.add(root);
        while(!stack.isEmpty()){
            root = stack.pollLast();
            res.add(root.val);
            if(root.right != null){
                stack.add(root.right);
            }
            if(root.left != null){
                stack.add(root.left);
            }
        }
        return res;
    }
}

emmmm....事实证明这段代码人家提交超过百分百,我提交好几次也都只超过百分之五十八。。和我之前的一样的。。。行了行了,就这样了,下一题是后续遍历。

二叉树的后序遍历

题目:给定一个二叉树,返回它的 后序 遍历。进阶: 递归算法很简单,你可以通过迭代算法完成吗?

思路:题目截图就不截图了,知道是后序遍历就行了,我直接贴代码了。
递归版本:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    List<Integer> res;
    public List<Integer> postorderTraversal(TreeNode root) {
        res = new ArrayList<Integer>();
        post(root);
        return res;
    }
    public void post(TreeNode root){
        if(root == null) return;
        post(root.left);
        post(root.right);
        res.add(root.val);
    }
}

迭代版本:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    public List<Integer> postorderTraversal(TreeNode root) {
        LinkedList<Integer> res = new LinkedList<Integer>();
        if(root == null) return res;
        LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
        stack.add(root);
        while(!stack.isEmpty()){
            root = stack.poll();
            if(root.left !=null ) stack.push(root.left); 
            if(root.right != null) stack.push(root.right);
            res.addFirst(root.val);
        }
        return res;
    }
}

其实这个题就是上题的逆思路。递归就不说了,迭代的话如果是前序是 当前 + 左 +右。后续是 左 + 右 +当前。
其实左右是一样的,但是当前要去后面。 换个思路 如果实现了 当前 +右 +左 则倒过来直接就是后序遍历了。就这个思路。然后每次add都是添加到第一个,还有先放左再放右。
感觉也没啥说的,刚刚做才发现后序遍历是困难的,哈哈,突然对自己有信心了呢~~下一题了啊

LRU缓存机制

题目:运用你所掌握的数据结构,设计和实现一个 LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。
获取数据 get(key) - 如果密钥 (key) 存在于缓存中,则获取密钥的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果密钥不存在,则写入其数据值。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
进阶:你是否可以在 O(1) 时间复杂度内完成这两种操作?

示例:
LRUCache cache = new LRUCache( 2 /* 缓存容量 */ );
cache.put(1, 1);
cache.put(2, 2);
cache.get(1); // 返回 1
cache.put(3, 3); // 该操作会使得密钥 2 作废
cache.get(2); // 返回 -1 (未找到)
cache.put(4, 4); // 该操作会使得密钥 1 作废
cache.get(1); // 返回 -1 (未找到)
cache.get(3); // 返回 3
cache.get(4); // 返回 4

思路:这个题怎么说呢,我觉得实现起来还是很简单的,尤其是进阶要求只要求了时间复杂度而没有空间复杂度。。我目前的想法是用LinkedHashMap。然后put判断下size,达到容量了则把第一个删了,然后后一个加上。没达到直接加。 然后get的时候先把这个key-value获取了,然后把这个key删除了,重新添加,保证用过的在最后,第一个的永远是最不活跃的那个。。差不多就这样,我去代码实现下。
尴尬了,我发现LinkedHashMap自带访问顺序,就是访问完移到最后,,,哈哈。其实这个类我早就知道,但是工作中几乎没用到过,只知道是Linked(链表)+HashMap的合体,本来我以为只是有序的map呢。。。刚刚要用了去百度了下api才发现不太多。。我用这个数据结构是不是太取巧了啊?不管了,反正第一版本先实现再说。
好了,在前人的肩膀上直接实现了:

class LRUCache {
    LinkedHashMap<Integer,Integer> map;

    public LRUCache(int capacity) {
        this.map = new LinkedHashMap<Integer, Integer>(capacity, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry eldest) {
                return map.size() > capacity;
            }
        };
    }
    
    public int get(int key) {
        return map.get(key)==null?-1:map.get(key);
    }
    
    public void put(int key, int value) {
        map.put(key,value);
    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

我仅剩不多的自尊心告诉我这道题不是考对Linked Hash Map的熟悉程度的。。。我这是取巧了啊,我自己实现试试。
其实我觉得用LinkedList和HashMap也是可以实现的。链表存key,map的key还是key,value是value。然后链表就按照我刚刚说的,超了再放则删除第一个。重复访问则删除再添加保证访问的在最后。我去实现下看看。
自己手写出来了,效率啥的贼辣眼睛。。。我先贴出来:

class LRUCache {
    int cap;
    HashMap<Integer,Integer> map;
    LinkedList<Integer> list;
    public LRUCache(int capacity) {
        this.cap = capacity;
        map = new HashMap<Integer,Integer>();
        list = new LinkedList<Integer>();
    }
    
    public int get(int key) {
        if(map.get(key) != null){
            list.remove(Integer.valueOf(key));
            list.add(key);
            return map.get(key);
        }
        return -1;
    }
    
    public void put(int key, int value) {
        if(list.size()==cap && !list.contains(key)){
            Integer r = list.get(0);
            list.remove(0);
            map.remove(r);
            list.add(key);
            map.put(key,value);
        }else if(list.contains(key)){//说明key已经存在,是更改值            
            list.remove(Integer.valueOf(key));
            list.add(key);
            map.put(key,value);
        }else{
            list.add(key);
            map.put(key,value);
        }

    }
}

/**
 * Your LRUCache object will be instantiated and called as such:
 * LRUCache obj = new LRUCache(capacity);
 * int param_1 = obj.get(key);
 * obj.put(key,value);
 */

就是linkedList 来排序, map来存值。难道是不难,就是很墨迹。这个题就这样了。
今天的笔记就记到这里,如果稍微帮到你了记得点个喜欢点个关注,顺便祝大家工作顺顺利利,生活平平安安,周末愉快!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容