Interview Questions: Hash Tables

本文探讨了4-SUM问题的高效解决方案,利用Hash表实现O(n^2)的时间复杂度。同时,深入分析了在使用自定义类作为Hash表键时,hashCode()与equals()方法的正确实现对性能的影响。

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

Hash Tables

4-SUM. Given an array a[] of nn integers, the 4-SUM problem is to determine if there exist distinct indices i, j, k, and l such that a[i]+a[j]=a[k]+a[l]. Design an algorithm for the 4-SUM problem that takes time proportional to n 2 n^2 n2 (under suitable technical assumptions).

遍历i、j,先查找hash表中是否已存在a[i]+a[j],没有则将和存入hash表中。

public class FourSUM {
    public boolean exist(int[] a) {
        Set<Integer> hash = new HashSet<>();

        for (int i = 0; i < a.length - 1; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (hash.contains(a[i] + a[j])) {
                    return true;
                }
                hash.add(a[i] + a[j]);
            }
        }

        return false;
    }
}

Hashing with wrong hashCode() or equals(). Suppose that you implement a data type ?????????????? for use in a ????.????.???????.

  • Describe what happens if you override ????????() but not ??????().
  • Describe what happens if you override ??????() but not ????????().
  • Describe what happens if you override ????????() but implement public boolean equals(OlympicAthlete that) instead of public boolean equals(Object that).
  1. 只重写了hashCode(),但equals()仍是只当两引用为同一对象时才返回true。那么当插入两个有相同name的对象时,hashCode()相同,但equals()为false,会在同一下标处插入两个相同的name。

  2. 只重写了equals(),但hashCode()仍是默认返回对象的地址。那么当插入两个有相同name 的对象时,equals()为true,但hashCode()不同,会在不同下标处插入两个相同的name。

  3. 用以下用例进行测试,证明调用仍是equals(Object that)。分析原因,可能是因为java的泛型是通过类型擦除实现的,在运行时所有的Key类型都会被擦除为Object,因此也只会调用equals(Object that)。

    import java.util.HashMap;
    
    public class Test {
        String name;
    
        public Test(String name) {
            this.name = name;
        }
    
        @Override
        public int hashCode() {
            return name.hashCode();
        }
    
        public boolean equals(Test that) {
            if (that == null) {
                return false;
            }
            return that.name.equals(this.name);
        }
    
        public static void main(String[] args) {
            HashMap<Test, Boolean> map = new HashMap<>();
            map.put(new Test("Li"), true);
            map.put(new Test("Li"), true);
            map.put(new Test("Li"), true);
            map.put(new Test("Li"), true);
            System.out.println(map.size());			// 输出 4
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值