ARTS 2019 02 23 (19)

68 篇文章 0 订阅
49 篇文章 0 订阅

ARTS
Algorithm:每周至少做一个leetcode的算法题;
Review:阅读并点评至少一篇英文技术文章;
Tip/Tech:学习至少一个技术技巧;
Share:分享一篇有观点和思考的技术文章;

Algorithm

387. 字符串中的第一个唯一字符

https://leetcode-cn.com/problems/first-unique-character-in-a-string/

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
案例:
s = “leetcode”
返回 0.
s = “loveleetcode”,
返回 2.
注意事项:您可以假定该字符串只包含小写字母。

这里的常规解法,就是遍历,然后把数据记录到哈希表里,每条数据按照顺序存储,其实代码看起来是很简单易懂的,show the code:

class Solution {
    public int firstUniqChar(String s) {
        int  len = s.length();
        LinkedHashMap<Character, Integer> map = new LinkedHashMap<>();
        for (int i = 0; i < len; ++i) {
            char temp = s.charAt(i);
            if (map.containsKey(temp)) {
                map.put(temp, map.get(temp) + 1);
            } else {
                map.put(temp, 1);
            }
        }
        for (Character item : map.keySet()) {
            if (map.get(item) == 1) {
                return s.indexOf(item);
            }
        }
        return -1;
    }
}

但是提交之后才发现,原来这题有着更加高明的解法,解题的方法简直让我眼前一亮,直接遍历26个字母,如果说这个字母出现的位置就是最后出现的位置,那么就进行比较,比较这个字母和之前的记录的结果(res)哪个小,哪个小用哪个,当然,第一次发现这种字母的时候,就把它赋值给结果(res)

class Solution {
    public int firstUniqChar(String s) {
        int res = -1;
        for(char c = 'a' ;c <= 'z' ; c ++ ){
            int idx = s.indexOf(c);
            if(idx != -1 && idx == s.lastIndexOf(c)){
                res = (res == -1) ? idx : Math.min(res , idx);
            }
        }
        return res;
    }
}

217. 存在重复元素

https://leetcode-cn.com/problems/contains-duplicate/

给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true

这道题这个礼拜给我带来的收获最多,这是关于代码如何优化到极致的一种收获。这道题目其实很简单,只要你能想到用Java里面的数据结构Set来进行进行判断就是最快的做法了,但是就是这个最快做法,却输给了大部分的提交,先来看看原来的代码是咋写的:

//通过	26 ms	41.4 MB	java
public boolean containsDuplicate(int[] nums) {
        int len = nums.length;
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < len; ++i) {
            if (set.contains(nums[i])) {
                return true;
            } else {
                set.add(nums[i]);
            }
        }
        return false;
    }

这种效率无疑是被吊起来打的,但是思想没有错啊。那么代码应该如何去优化?

// 通过	9 ms	34.4 MB
public boolean containsDuplicate(int[] nums) {
        int len = nums.length;
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < len; ++i) {
            boolean addResult = set.add(nums[i]);
            if (!addResult) {
                return true;
            }
        }
        return false;
    }

contains 这个方法比add这个方法的效率慢的真的太多了, 这题给我带来的收获真的是,平时我们在写代码的过程中是不注重函数的使用的,对于代码的效率而言也是得过且过的,但是这次给我带来的感觉就是,你最好要明白每个函数到底表达了什么,最好要知道每个函数的运行机制是什么。
我大胆的猜测一下:add是直接根据参数计算哈希值,然后根据哈希值来判断是否存在;而contains则是去遍历整个set来判断这个值是否存在。其实感觉这个有点说不通啊,contains也是可以计算哈希值的,没有道理去遍历啊。最好还是看一下字节码来进行做判断了。

Review

https://www.techiedelight.com/determine-linked-list-palindrome-or-not/
这篇文章提供的一个思路就是用栈来把数据存储起来,然后不断的出栈进行每个元素的比较。这个倒是个非常简单好懂的做法。
我们一般判断一个链表是否回文,一般都是先找出中间结点,然后根据中间结点,把后面的节点进行遍历反转,然后进行分别判断,这么做倒是省了不少的空间,但是代码写起来难度有点高,涉及到链表反转,肯定是要费一番功夫的。

Tip/Tech

学习并且使用了二叉树的前序、中序、后序遍历方式,做了很多道关于二叉树的题。

Share

http://nautil.us/issue/68/context/what-impossible-meant-to-feynman
『不可能』对费曼先生来说意味着什么?
这篇文章真的是说的,特别的琐碎,更像是带着对费曼先生的感谢之情的回忆。说了好多关于费曼先生的日常的言行举止等等。
费曼先生在面对自己以前没有见过的时候,常常会说『Impossible』,表示自己的震惊。
感觉费曼先生对作者影响深远啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值