返回

技术面试题搞不懂?两大互联网巨头教你“躺平”!

前端

攻克技术面试:揭秘阿里和腾讯面试真题

对于技术工作的面试,编程能力和算法理解力往往是重中之重。阿里巴巴和腾讯作为业界巨头,其面试题更是深受求职者关注。本文将深入剖析这两道经典面试题,助你轻松应对技术面试。

阿里巴巴面试题:数组去重

题目解读

给定一个整数数组,要求去除其中重复元素,返回一个不含重复元素的新数组。

算法思路

方法一:利用哈希表

  • 使用一个哈希表存储数组中出现的元素,键为元素值,值为 True。
  • 遍历数组,如果哈希表中不存在当前元素,则将其添加到哈希表并加入结果数组。

代码示例:

import java.util.HashMap;
import java.util.HashSet;

public class ArrayDistinct {

    public static int[] distinct(int[] array) {
        if (array == null || array.length == 0) {
            return new int[0];
        }

        // 使用哈希表存储元素
        HashMap<Integer, Boolean> hashtable = new HashMap<>();

        // 使用结果数组存储不重复的元素
        int[] result = new int[array.length];
        int index = 0;

        for (int element : array) {
            // 如果元素不在哈希表中,则添加它并加入结果数组
            if (!hashtable.containsKey(element)) {
                hashtable.put(element, true);
                result[index++] = element;
            }
        }

        return result;
    }

    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5, 1, 2, 3};
        int[] distinctArray = distinct(array);

        for (int element : distinctArray) {
            System.out.println(element);
        }
    }
}

方法二:利用 HashSet

  • HashSet 是一个不存储重复元素的集合。
  • 遍历数组,将元素添加到 HashSet 中。
  • 将 HashSet 转换为数组,即为不重复元素数组。

代码示例:

import java.util.HashSet;

public class ArrayDistinct {

    public static int[] distinct(int[] array) {
        if (array == null || array.length == 0) {
            return new int[0];
        }

        // 使用 HashSet 去除重复元素
        HashSet<Integer> set = new HashSet<>();
        for (int element : array) {
            set.add(element);
        }

        // 将 HashSet 转换为数组
        int[] result = new int[set.size()];
        int index = 0;
        for (Integer element : set) {
            result[index++] = element;
        }

        return result;
    }

    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5, 1, 2, 3};
        int[] distinctArray = distinct(array);

        for (int element : distinctArray) {
            System.out.println(element);
        }
    }
}

腾讯面试题:链表反转

题目解读

给定一个链表的头节点,要求反转链表并返回新的头节点。

算法思路

方法一:迭代法

  • 将当前节点的下一个节点存储在 next 变量中。
  • 将当前节点的下一个节点指向 prev 变量,prev 变量存储当前节点的上一个节点。
  • 将 prev 变量更新为当前节点。
  • 将 next 变量更新为当前节点的下一个节点。
  • 重复以上步骤,直到 current 为 null。

代码示例:

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}

public class LinkedListReverse {

    public static ListNode reverse(ListNode head) {
        ListNode prev = null;
        ListNode current = head;

        while (current != null) {
            ListNode next = current.next;
            current.next = prev;
            prev = current;
            current = next;
        }

        return prev;
    }

    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(4);
        head.next.next.next.next = new ListNode(5);

        ListNode reversedHead = reverse(head);

        while (reversedHead != null) {
            System.out.println(reversedHead.val);
            reversedHead = reversedHead.next;
        }
    }
}

方法二:递归法

  • 如果 current 为 null,则返回 prev。
  • 递归调用 reverse(current.next),并更新 current.next 为 prev。
  • 将 prev 更新为 current。
  • 返回 prev。

代码示例:

public class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }
}

public class LinkedListReverse {

    public static ListNode reverse(ListNode head) {
        return reverse(head, null);
    }

    private static ListNode reverse(ListNode current, ListNode prev) {
        if (current == null) {
            return prev;
        }

        ListNode next = current.next;
        current.next = prev;
        prev = current;
        current = next;

        return reverse(current, prev);
    }

    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(4);
        head.next.next.next.next = new ListNode(5);

        ListNode reversedHead = reverse(head);

        while (reversedHead != null) {
            System.out.println(reversedHead.val);
            reversedHead = reversedHead.next;
        }
    }
}

总结

通过这两道经典面试题,我们了解到技术面试不仅考察编程能力,更考察算法理解力、问题解决能力和思维敏捷性。掌握扎实的算法和数据结构知识、勤加练习并保持良好的心态,才能在技术面试中脱颖而出。

常见问题解答

1. 如何选择合适的算法去重数组?

  • 如果数组元素较少,则可以使用时间复杂度为 O(n^2) 的双重循环遍历。
  • 如果数组元素较多,则可以使用时间复杂度为 O(n) 的哈希表或 HashSet。

2. 链表反转的递归法和迭代法有什么区别?

  • 递归法使用函数调用栈,而迭代法使用一个显式循环。
  • 递归法代码简洁,而迭代法执行效率更高。

3. 如何应对大量重复元素的数组去重问题?

  • 对于大量重复元素的数组,可以使用基于计数的算法,如桶排序或基数排序。
  • 这些算法的时间复杂度与元素个数的范围相关,而不是数组的大小。

4. 如何处理链表中存在环的情况?

  • 使用快慢指针法。一个指针每次移动一步,另一个指针每次移动两步。
  • 如果存在环,则快指针最终将追上慢指针。

5. 如何提高技术面试的通过率?

  • 扎实掌握算法和数据结构知识。
  • 勤加练习,提升编程能力。
  • 保持良好的心态,自信沉着地应对面试。