哈希表实战(求和,计算个数)

本文通过三个编程实战例子,展示了如何使用Hash函数和数据结构来高效解决算法问题。实战1介绍了利用字母异位词判断和Map计数法实现;实战2通过Map快速找到两数之和;实战3探讨了不同方法解决三数之和问题,包括排序和双指针法。这些案例揭示了在算法设计中合理运用数据结构的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概念:Hash 函数之入土攻略

实战 1:有效的字母异位词

解题思路:

思路1: 对单词的字母进行排序,看最终结果是否一致,如:rat ->art rat -> art

思路2: 采用 Map 数据结构,计算每个字母出现的次数

class Solution {
    public boolean isAnagram(String s, String t) {
        char[] sChars = s.toCharArray();
        char[] tChars = t.toCharArray();
        Arrays.sort(sChars);
        Arrays.sort(tChars);
        return Arrays.equals(sChars, tChars);
    }
}
class Solution {
    public boolean isAnagram(String s, String t) {
        int[] counts = new int[26];
        t.chars().forEach(item -> counts[item - 'a']++);
        s.chars().forEach(item -> counts[item - 'a']--);
        return Arrays.stream(counts).allMatch(item -> item == 0);
    }
}

实战2:两数之和

解题思路:

思路1:暴力求解。两层循环,时间复杂度 O(n*n)。

思路2: 采用 Map 集合。x+y=9,y=9-x。遍历一遍 x,时间复杂度 O(n)。

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int i=0; i<nums.length; i++){
            for(int j=i+1; j<nums.length; j++){
                if(nums[i]+nums[j] == target){
                    return new int[]{i, j};
                }
            }
        }
        return new int[0];
    }
}
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; ++i) {
            if (map.containsKey(target - nums[i])) {
                return new int[]{map.get(target - nums[i]), i};
            }
            map.put(nums[i], i);
        }
        return new int[0];
    }
}

实战3:三数之和

解题思路:参考

思路1:暴力求解,3 层循环。时间复杂度 O(n*n*n)。

思路2:采用 Map,2 层循环。a+b+c=0,c=0-(a+b)。时间复杂度 O(n*n)。

思路3:先排序后查找,时间复杂度 O(n*n)。

step 1 排序 Arrays.sort(nums)

step 2 初始化左右指针

step 3 sum < 0 L++

step 3 L 与 R 相遇 或 L > R,i ++

step 4 sum == 0,L++,R--

 step 5 sum > 0,R--

class Solution {
        public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList();
        int len = nums.length;
        if(nums == null || len < 3) return list;
        Arrays.sort(nums); // 排序
        for (int i = 0; i < len ; i++) {
            if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
            if(i > 0 && nums[i] == nums[i-1]) continue; // 则说明该数字重复,会导致结果重复,所以应该跳过
            int L = i+1;//指针从第二个数开始移动
            int R = len-1;
            while(L < R){
                int sum = nums[i] + nums[L] + nums[R];
                if(sum == 0){
                    list.add(Arrays.asList(nums[i],nums[L],nums[R]));
                    while (L<R && nums[L] == nums[L+1]) L++; // 则会导致结果重复,应该跳过
                    while (L<R && nums[R] == nums[R-1]) R--; // 则会导致结果重复,应该跳过
                    L++;
                    R--;
                }
                else if (sum < 0) L++;
                else if (sum > 0) R--;
            }
        }
        return list;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值