开始学算法5===>哈希表基础(LeetCode刷题!!!)

跟着carl哥的第五天

一般哈希表都是用来快速判断一个元素是否出现集合里

哈希表基础

HashSet简单的理解就是HashSet对象中不能存储相同的数据,存储数据时是无序的。但是HashSet存储元素的顺序并不是按照存入时的顺序(和List显然不同) 是按照哈希值来存的所以取数据也是按照哈希值取得。

做算法题中set的基本用法

//初始化
Set<Integer> set = new HashSet<>();

//添加数据
set.add(1);

//判断set中是否有该元素(返回boolean值)
set.contain(i);

//移除元素
set.remove(i);

//清空set
set.clear();

//获取长度
set.size();

HashMap是一个集合,键值对的集合,源码中每个节点用Node<K,V>表示(键值对)。K唯一

做算法题中map的基本用法

//初始化map
Map<Integer, Integer> map = new HashMap<>();

//添加数据
map.put(key, value);

//通过key查看是否包含该元素
map.containsKey();

最主要就是记得 它们是能在一个集合中最快查询到某一元素的就行,而且key都是唯一。

先看第一道题

leetcode242.有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例1:

输入:s = "anagram", t = "nagaram"    
输出: true

示例2:

输入: s = "rat", t = "car"
输出: false

思路:
这道题只需要记得只有26位小写字母,只需要用数组下标代表每一个字母,且数组的值表示该字母出现多少次并统计即可,最后再遍历一次,检查是否符合题目要求


答案:::

public class test01 {

    //定义输入输出
    public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {

        //读入一行,并按照空格拆分
        String s = in.readLine();
        String t = in.readLine();

        boolean flag = isAnagram(s, t);

        System.out.println(flag);
        out.flush();
        out.close();

    }

    private static boolean isAnagram(String s, String t) {

        int[] record = new int[26];
        for (int i = 0; i < s.length(); i ++) {
            record[s.charAt(i) - 'a'] ++;
        }
        for (int i = 0; i < t.length(); i ++) {
            record[t.charAt(i) - 'a'] --;
        }
        for (int count : record) {
            if (count != 0)
                return false;
        }

        return true;
    }
}

再看第二道题

leetcode349. 两个数组的交集

给定两个数组,编写一个函数来计算它们的交集。

示例1 :

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例2 :

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

思路:因为我们要判断数组相交的元素,所以我们就考虑用数组,还是hashset,或者hashmap,数组的话就是O(n2) 如果时hashset或者hashmap会快一点,而且可以注意到的是hashset或者hashmap刚好key都是不可重复的,刚好符合实例1,同时也不用考虑输出顺序,最后用hashset也是因为我们只需要存一个元素,而不需要存储一对,故使用hashset


答案:

public class test02 {

    //定义输入输出
    public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {

        //读入一行,并按照空格拆分
        String[] s = in.readLine().split(",");
        String[] t = in.readLine().split(",");
        int[] arr1 = new int[s.length];
        int[] arr2 = new int[t.length];

        for (int i = 0; i < s.length; i ++) {

            arr1[i] = Integer.parseInt(s[i]);
        }
        for (int i = 0; i < t.length; i ++) {

            arr2[i] = Integer.parseInt(t[i]);
        }

        int[] result = intersection(arr1, arr2);

        out.write(result.toString());
        out.flush();
        out.close();
        //System.out.println(Arrays.toString(arr));

    }

    private static int[] intersection(int[] arr1, int[] arr2) {

        if (arr1 == null || arr1.length == 0 || arr2 == null || arr2.length == 0)
            return new int[0];

        Set<Integer> set = new HashSet<>();
        for (int i : arr1) {
            set.add(i);
        }

        Set<Integer> resultSet = new HashSet<>();
        for (int i : arr2) {
            if (set.contains(i)) {
                resultSet.add(i);
            }
        }

        int[] result = new int[resultSet.size()];
        int index = 0;
        for (Integer item : resultSet) {
            result[index ++] = item;
        }

        return result;
        /*return result.stream().mapToInt(x -> x).toArray();*/
    }
}

第三道题

leetcode202. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。如果 n 是快乐数就返回 True ;不是,则返回 False 。

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。

示例:

输入:19
输出:true
解释:
1^2 + 9^2 = 82
8^2 + 2^2 = 68
6^2 + 8^2 = 100
1^2 + 0^2 + 0^2 = 1

思路:
题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现。如果重复出现的话用set.contain()就可以判断这个数是不是快乐数


答案:

public class test03 {

    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

    public static void main(String[] args) throws IOException {

        Integer n = Integer.parseInt(in.readLine());
        boolean flag = isHappy(n);
        System.out.println(flag);
    }

    //判断快乐数  一个数各位数没有一直重复出现 或者 相加后结果等于1
    private static boolean isHappy(Integer n) {

        Set<Integer> record = new HashSet<>();

        while(n != 1 && !record.contains(n)) {
            record.add(n);

            //计算各位数的相加和
            n = getNextNumber(n);
        }
        return n == 1;
    }

    private static int getNextNumber(Integer n) {

        int res = 0;
        while(n > 0) {

            int temp = n % 10;
            res += temp * temp;
            n = n / 10;
        }

        return res;
    }
}

最后一道坚持一下!!!!

leetcode1.两数之和

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例1:

输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
所以返回 [0, 1]

示例2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例3:

输入:nums = [3,3], target = 6
输出:[0,1]

思路:
这道题就要用hashmap了,因为要返回数组的下标,然后我们还要匹配两个整数,所以用map的key存储整数值,value存储下标。
!!!记住实例三,你错的可能会是这个地方!!!
用for循环遍历一遍数组,然后再判断之前遍历过的元素中的Key有没有刚好时等于(target-nums[i]),有的话存入新数组并返回


答案:

public class test04 {

    //定义输入输出
    public static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    public static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {

        //读入一行,并按照空格拆分
        String s = in.readLine();
        String[] str = s.split(",");

        //转为int数组
        int[] nums = new int[str.length];
        for (int i = 0; i < str.length; i ++) {
            nums[i] = Integer.parseInt(str[i]);
        }

        int target = Integer.parseInt(in.readLine());

        int[] arr = twoSum(nums, target);
        out.write(Arrays.toString(arr));
        out.flush();
        out.close();
        //System.out.println(Arrays.toString(arr));

    }

    private static int[] twoSum(int[] nums, int target) {

        Map<Integer, Integer> map = new HashMap<>();
        int[] res = new int[2];

        if (nums.length < 2 || nums == null)
            return null;

        for (int i = 0; i < nums.length; i ++) {

            //如果map包含了一个key(一个target-nums[i]) 且 下标不等
            if (map.containsKey(target - nums[i])) {
                res[0] = map.get(target - nums[i]);
                res[1] = i;
            }
            map.put(nums[i], i);
        }

        return res;
    }
}

自我总结

学习了哈希表的基础用法
朋友仍需努力 一起加油
兄弟萌冲啊!

大概就是这样,大家懂了吗 有什么不懂的评论区评论或者私信我吧!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值