《火车驶入驶出顺序验证问题》和《计算特定条件下的四元组数量》 | 豆包MarsCode AI刷题

127 阅读3分钟

今天我们将在豆包MarsCode AI刷题平台上,完成《火车驶入驶出顺序验证问题》与《计算特定条件下的四元组数量》这两个算法问题,通过这些练习提升用户解决此类问题的能力

《火车驶入驶出顺序验证问题》题面如下:

image.png

注:这道题的难度竟然标记的是困难,在别的平台上应该最多就是个中等

解题思路:

很经典的模拟栈问题,我们要熟练运用栈先进后出的性质,任何先驶进休息区的火车肯定是后驶出:

  • 1、先设置一个模拟火车在休息区停留情况的栈stack
  • 2、根据火车驶出的顺序,遍历数组b,获得当前驶出的火车i
  • 3、接下来只有栈顶的火车可以驶出,这个火车必须是i车,所以:
    • 如果当前栈顶火车不是i车:
      • i车已经驶进休息区,即在栈中且不在栈顶,这种情况无论如何下一个驶出的火车都不会是i车,所以其实可以返回false,但是在我们的实现中这么做的前提是后续所有a中元素都已经入栈
      • i车还没有驶进休息区,那么为了让下一个驶出的车为i车,我们要让i车之前的所有车先驶进休息区,即把i元素之前的所有元素入栈(根据a中的顺序)(在我们的实现中包括i元素)
    • 如果当前栈顶火车是i车:
      • 弹出栈顶火车
  • 4、如果能遍历完b中所有元素,说明所有火车都可以以b中的顺序驶出,返回true;否则在上面任何一步无法进行下去都说明这个顺序不成立,可以立即返回false

具体实现:

import java.util.Stack;

public class Main {
    public static boolean solution(int n, int[] a, int[] b) {
        // write code here
        Stack<Integer> stack = new Stack<>();
        int pa = 0;
        for (int i : b) {
            while (stack.isEmpty() || stack.peek() != i) {
                if (pa >= n) {
                    return false;
                } else {
                    stack.push(a[pa]);
                    pa++;
                }
            }
            if (!stack.isEmpty() && stack.peek() == i) {
                stack.pop();
            } else {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(solution(3, new int[]{1, 2, 3}, new int[]{1, 2, 3}) == true);
        System.out.println(solution(3, new int[]{1, 2, 3}, new int[]{3, 2, 1}) == true);
        System.out.println(solution(3, new int[]{1, 2, 3}, new int[]{3, 1, 2}) == false);
    }
}

《计算特定条件下的四元组数量》题面如下:

image.png

解题思路:

  • 预处理

    • 对于每个可能的 (i,j)(i, j) 对,计算 ai+aja_i + a_j 并存储在哈希表中。
    • 对于每个可能的 (k,l)(k, l) 对,计算 akala_k \oplus a_l 并存储在另一个哈希表中。
  • 计算结果

    • 遍历所有可能的 (i,j)(i, j) 对,检查是否存在对应的 (k,l)(k, l) 对满足条件。

具体实现:

import java.util.*;
public class Main {
    static final int MOD = 1_000_000_007;

    public static int solution(int n, int[] a) {
        int ret = 0;
        Map<Integer, Integer> right = new HashMap<>();

        // 预处理 (k, l) 对
        for (int k = n - 2; k >= 1; k--) {
            for (int l = k + 1; l < n; l++) {
                int xorValue = a[k] ^ a[l];
                right.put(xorValue, right.getOrDefault(xorValue, 0) + 1);
            }
        }

        // 遍历 (i, j) 对
        for (int j = 1; j <= n - 3; j++) {
            Map<Integer, Integer> left = new HashMap<>();

            // 计算 (i, j) 对
            for (int i = 0; i < j; i++) {
                int sumValue = a[i] + a[j];
                left.put(sumValue, left.getOrDefault(sumValue, 0) + 1);
            }

            // 更新 right 哈希表
            for (int l = j + 1; l < n; l++) {
                int xorValue = a[j] ^ a[l];
                right.put(xorValue, right.getOrDefault(xorValue, 0) - 1);
            }

            // 检查是否存在满足条件的 (k, l) 对
            for (Map.Entry<Integer, Integer> entry : left.entrySet()) {
                int key = entry.getKey();
                int value = entry.getValue();
                if (right.containsKey(key)) {
                    ret = (ret + value * right.get(key)) % MOD;
                }
            }
        }

        return ret;
    }

    public static void main(String[] args) {
        System.out.println(solution(5, new int[]{2, 3, 1, 5, 4}) == 1);
        System.out.println(solution(6, new int[]{1, 2, 3, 4, 5, 6}) == 1);
        System.out.println(solution(4, new int[]{4, 1, 3, 2}) == 0);
    }
}

算法的时间复杂度:O(nlog(n2))O(nlog(n^2))

空间复杂度:O(n2)O(n^2)

可以通过本题:

image.png

借助豆包MarsCode AI刷题平台,我们不仅高效地解决了《火车驶入驶出顺序验证问题》和《计算特定条件下的四元组数量》,还加深了对相关算法和数据结构的理解,后续会借助豆包MarsCode AI给大家展示更多题目的讲解