Google 面试经验分享:数组相等元素对算法题 - Oavoservice

2025-07-18
Google 面试经验分享:数组相等元素对算法题 - Oavoservice 封面

🎤 Google 0718 面经

👩‍💻 Candidate 在 Google 面试中遇到了一个经典的数组相等元素对算法题。

📋 题目要求

给定长度为N的数组a[0..N-1],要求选出一对下标i≤j,满足 a[i] = a[j]。根据这些要求生成一篇面经。

📝 具体说明

  • 需要找到数组中值相等的元素对
  • 下标i必须小于等于下标j
  • 需要统计所有可能的相等元素对
  • 考虑重复元素的情况

❓ 问题分析

这是一个典型的数组统计问题

  • 核心思想:统计每个值的出现次数
  • 关键点:使用哈希表记录频率
  • 优化:可以一次遍历完成统计

💡 思路设计

使用哈希表统计:

  1. 遍历数组,统计每个值的出现次数
  2. 对于出现n次的元素,可以形成C(n,2)个对
  3. 累加所有元素的对数

💻 代码实现

import java.util.*;

public class ArrayEqualPairs {
    
    // 方法1:哈希表统计 - 最优解
    public int countEqualPairs(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        
        Map<Integer, Integer> frequency = new HashMap<>();
        
        // 统计每个元素的出现次数
        for (int num : arr) {
            frequency.put(num, frequency.getOrDefault(num, 0) + 1);
        }
        
        int totalPairs = 0;
        
        // 计算每个值的对数
        for (int count : frequency.values()) {
            if (count >= 2) {
                // C(count, 2) = count * (count - 1) / 2
                totalPairs += count * (count - 1) / 2;
            }
        }
        
        return totalPairs;
    }
    
    // 方法2:暴力解法 - 双重循环
    public int countEqualPairsBruteForce(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        
        int count = 0;
        int n = arr.length;
        
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) { // j从i开始,满足i≤j
                if (arr[i] == arr[j]) {
                    count++;
                }
            }
        }
        
        return count;
    }
    
    // 方法3:排序后统计连续相同元素
    public int countEqualPairsSorted(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        
        Arrays.sort(arr);
        int totalPairs = 0;
        int currentCount = 1;
        
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] == arr[i - 1]) {
                currentCount++;
            } else {
                // 处理前一个值的所有对数
                if (currentCount >= 2) {
                    totalPairs += currentCount * (currentCount - 1) / 2;
                }
                currentCount = 1;
            }
        }
        
        // 处理最后一个值
        if (currentCount >= 2) {
            totalPairs += currentCount * (currentCount - 1) / 2;
        }
        
        return totalPairs;
    }
    
    // 方法4:返回所有相等元素对的下标
    public List<int[]> findAllEqualPairs(int[] arr) {
        List<int[]> pairs = new ArrayList<>();
        
        if (arr == null || arr.length == 0) {
            return pairs;
        }
        
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j < arr.length; j++) {
                if (arr[i] == arr[j]) {
                    pairs.add(new int[]{i, j});
                }
            }
        }
        
        return pairs;
    }
    
    // 方法5:使用数组作为哈希表(适用于小范围整数)
    public int countEqualPairsArray(int[] arr) {
        if (arr == null || arr.length == 0) {
            return 0;
        }
        
        // 假设数组中的值在0到1000之间
        int[] frequency = new int[1001];
        
        for (int num : arr) {
            frequency[num]++;
        }
        
        int totalPairs = 0;
        for (int count : frequency) {
            if (count >= 2) {
                totalPairs += count * (count - 1) / 2;
            }
        }
        
        return totalPairs;
    }
    
    // 测试方法
    public static void main(String[] args) {
        ArrayEqualPairs solution = new ArrayEqualPairs();
        
        // 测试用例1:基本测试
        int[] arr1 = {1, 2, 3, 2, 1};
        System.out.println("测试1 - 哈希表: " + solution.countEqualPairs(arr1)); // 2
        System.out.println("测试1 - 暴力: " + solution.countEqualPairsBruteForce(arr1)); // 2
        System.out.println("测试1 - 排序: " + solution.countEqualPairsSorted(arr1)); // 2
        
        // 测试用例2:重复元素较多
        int[] arr2 = {1, 1, 1, 1};
        System.out.println("测试2 - 哈希表: " + solution.countEqualPairs(arr2)); // 6
        System.out.println("测试2 - 暴力: " + solution.countEqualPairsBruteForce(arr2)); // 6
        
        // 测试用例3:无重复元素
        int[] arr3 = {1, 2, 3, 4, 5};
        System.out.println("测试3 - 哈希表: " + solution.countEqualPairs(arr3)); // 5
        System.out.println("测试3 - 暴力: " + solution.countEqualPairsBruteForce(arr3)); // 5
        
        // 测试用例4:空数组
        int[] arr4 = {};
        System.out.println("测试4 - 哈希表: " + solution.countEqualPairs(arr4)); // 0
        
        // 测试用例5:单个元素
        int[] arr5 = {1};
        System.out.println("测试5 - 哈希表: " + solution.countEqualPairs(arr5)); // 1
        
        // 测试所有相等元素对
        int[] arr6 = {1, 2, 1, 2};
        List<int[]> pairs = solution.findAllEqualPairs(arr6);
        System.out.println("所有相等元素对:");
        for (int[] pair : pairs) {
            System.out.println("(" + pair[0] + ", " + pair[1] + ")");
        }
    }
}

🔍 算法分析

  • 哈希表方法时间复杂度:O(n),其中n是数组长度
  • 暴力解法时间复杂度:O(n²)
  • 排序方法时间复杂度:O(n log n)
  • 空间复杂度:O(n)(哈希表空间)

📊 测试用例

// 测试用例1:基本测试
arr = [1, 2, 3, 2, 1]
期望输出:2
解释:(0,4) 和 (1,3) 两对

// 测试用例2:重复元素较多
arr = [1, 1, 1, 1]
期望输出:6
解释:C(4,2) = 6 对

// 测试用例3:无重复元素
arr = [1, 2, 3, 4, 5]
期望输出:5
解释:每个元素与自己形成一对

// 测试用例4:空数组
arr = []
期望输出:0

// 测试用例5:单个元素
arr = [1]
期望输出:1

🚀 优化思路

面试官可能会问如何优化:

  • 哈希表优化:一次遍历完成统计,时间复杂度O(n)
  • 空间优化:如果值范围小,可以用数组代替哈希表
  • 并行处理:对于大数据集,可以考虑分块处理

✨ 面试官反馈

面试官对解决方案很满意:"Great solution! You've provided multiple approaches including the optimal hash table solution. The code is clean and handles edge cases well. Excellent understanding of combinatorics!"

面试技巧分享

在 Google 面试中,除了算法实现,面试官还会关注:

1. 问题理解能力

能够准确理解题目要求,特别是"i≤j"的约束条件。

2. 多种解法对比

提供哈希表、暴力、排序等多种解法,并分析其优缺点。

3. 数学知识应用

理解组合数学C(n,2)公式,正确计算对数。

4. 边界条件处理

考虑空数组、单个元素、无重复元素等特殊情况。

Oavoservice 实时辅助服务

在这次 Google 面试中,我们的实时辅助系统发挥了关键作用:

  • 问题分析:帮助候选人快速理解数组统计问题的本质
  • 算法指导:提供哈希表统计的核心思路
  • 数学公式:协助理解组合数学C(n,2)公式
  • 代码实现:协助完成完整的代码实现

结语

数组相等元素对是一道经典的数组统计问题,考察候选人对哈希表、组合数学的理解。在面试中,能够提供多种解法并分析其优缺点,展现了候选人的技术深度和数学基础。

如果你正在准备 Google 或其他公司的技术面试,欢迎联系 Oavoservice。我们拥有丰富的面试经验和专业的辅助团队,能够在你最需要的时候提供及时有效的帮助。

Oavoservice - 让每一次面试都成为成功的机会!

需要辅助的同学随时dd哦,vo开始前支持mock!