Day4_Hash, Leetcode 242, 349, 202 and 1

Leetcode 242:

https://leetcode.com/problems/valid-anagram/description/

题目的第一想法:

这道题的我个人的第一想法是使用直接hashtable,对存在的每个string A中的char做一个count。再在B中的string的char做一个count--。最后遍历整个hashtable来查看是不是所有的char的count都为零,如果不是return false,如果是return true。写法如下

class Solution {
    public boolean isAnagram(String s, String t) {
        HashMap<Character, Integer> map = new HashMap<>();
        StringBuilder sb = new StringBuilder(s);
        for(int i = 0; i < sb.length(); i++){
            if(map.containsKey(sb.charAt(i))){
                map.put(sb.charAt(i), map.get(sb.charAt(i)) + 1);
            }else{
                map.put(sb.charAt(i), 1);
            }
        }
        sb = new StringBuilder(t);
        for(int i = 0; i < sb.length(); i++){
            if(map.containsKey(sb.charAt(i))){
                map.put(sb.charAt(i), map.get(sb.charAt(i)) - 1);
            }else{
                return false;
            }
        }
        for(int c: map.values()){
            if(c != 0){
                return false;
            }
        }
        return true;
    }
}

更好的解法:

如果直接使用hashtable的话,在时间上很慢。个人的猜测是创建,遍历,更改一个较为复杂的数据结构需要的时间比较多。所以其实在这个问题上,直接使用一个数组来代替是更好的解法。因为数组的查找和更改在时间复杂度上和hashtable一样都是O(1)。写法如下

class Solution {
public:
    bool isAnagram(string s, string t) {
        int alpha[26] = {0};
        for(int i = 0; i < s.size(); i++){
            alpha[s[i] - 'a']++ ;
        }
        for(int i = 0; i < t.size(); i++){
            alpha[t[i] - 'a']-- ;
        }
        for(int i = 0; i <26; i++){
            if(alpha[i] != 0){
                return false;
            }
        }
        return true;
    }
};

Leetcode 349:

https://leetcode.com/problems/intersection-of-two-arrays/description/

题目的第一想法:

这道题我的第一想法是使用Hashset来储存第一个数组中的值,然后再用第二个数组中的值来对比hashset中储存的值进而得到intersection。使用hashset有两个天然优势,一是搜索速度较快,二是set不允许有重复值的存在避免了除重的冗余操作。写法如下

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        HashSet<Integer> set = new HashSet<>();
        HashSet<Integer> rset = new HashSet<>();
        for(int i = 0; i < nums1.length; i++){
            set.add(nums1[i]);
        }
        for(int i = 0; i < nums2.length; i++){
            if(set.contains(nums2[i])){
                rset.add(nums2[i]);
            }
        }
        int[] arr = new int[rset.size()];
        int i = 0;
        for(Integer num: rset){
            arr[i] = num;
            i++;
        }
        return arr;
    }
}

Leetcode 349:

https://leetcode.com/problems/intersection-of-two-arrays/description/

题目的第一想法:

这道题我没有看懂。对于“Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.”这句话我不是很理解它的意思。但大概可以理解为如果是1,就停止loop,如果不是就永远继续。但对于停止条件我刚开始依旧没有很好的想法。

看完代码随想录之后的想法:

看完之后我理解了使用Hashset的理由,确实本质上来说这道题依旧是一道查重的问题。个人感觉这种拨开表面看本质的能力还需要做更多的问题来培养。

class Solution {
    public boolean isHappy(int n) {
        HashSet<Integer> set = new HashSet<>();
        int num = numDet(n);
        while(num != 1 || !set.contains(num)){
            set.add(num);
            num = numDet(num);
            if(num == 1){
                return true;
            }else if(set.contains(num)){
                return false;
            }
        }
        return false;
    }

    public int numDet(int n){
        int sum = 0;
        while(n > 0){
            int num = n % 10;
            sum += num * num;
            n = n / 10;
        }
        return sum;
    }
}

Leetcode 1:

https://leetcode.com/problems/intersection-of-two-arrays/description/

题目的第一想法:

这道题因为以前做过比较多遍了,所以对各个解法都有了解。基本上有两种比较好的解法:一是用hashmap,另一种sort之后使用双指针。用hashmap的话时间复杂度是O(N),空间复杂的是O(N);而使用双指针的解法的时间复杂度则是O(nlgn)而空间复杂度则是O(N)。

以下是hashmap的思路:检查hash中有没有target-value的数字,如果有的话就返回pair。不然就将当前的value放入hash后继续检查其他数字。需要注意的是我们希望key是数组中存在的value,而index则需要储存在value的位置。写法如下

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] r = new int[2];
        HashMap<Integer, Integer> hash = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            if(hash.containsKey(target - nums[i])){
                r[0] = i;
                r[1] = hash.get(target - nums[i]);
                return r;
            }else{
                hash.put(nums[i], i);
            }
        }
        return r;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值