算法题

108 阅读6分钟

二进制之和

问题描述 小U和小R喜欢探索二进制数字的奥秘。他们想找到一个方法,将两个二进制字符串相加并以十进制的形式呈现。这个过程需要注意的是,他们的二进制串可能非常长,所以常规的方法可能无法处理大数。小U和小R希望你帮助他们设计一个算法,该算法能在保证时间复杂度不超过O(n^2)的前提下,返回两个二进制字符串的十进制求和结果。

解题思路

  1. 问题理解

    • 题目要求我们将两个二进制字符串相加,并以十进制的形式返回结果。
    • 二进制字符串可能非常长,因此需要处理大数。
  2. 数据结构选择

    • 由于二进制字符串可能非常长,直接使用整数类型(如 int 或 long)可能会导致溢出。
    • Java 提供了 BigInteger 类,专门用于处理大整数运算,因此选择 BigInteger 作为数据结构。
  3. 算法步骤

    • 将两个二进制字符串转换为 BigInteger 对象。
    • 使用 BigInteger 的 add 方法将两个 BigInteger 对象相加。
    • 将相加后的 BigInteger 对象转换回字符串形式,并返回结果。
  4. 代码实现

    • 使用 BigInteger 的构造函数将二进制字符串转换为 BigInteger 对象。
    • 调用 BigInteger 的 add 方法进行加法运算。
    • 使用 BigInteger 的 toString 方法将结果转换为字符串。

通过以上步骤,我们可以确保在处理大数时不会出现溢出问题,并且能够在 O(n^2) 的时间复杂度内完成计算。

代码实现:

import java.math.BigInteger;

public class Main {

    public static String solution(String binary1, String binary2) {
        // Please write your code here
        BigInteger num1 = new BigInteger(binary1, 2);  
        BigInteger num2 = new BigInteger(binary2, 2);  
        BigInteger sum = num1.add(num2);
        return sum.toString();
    }

    public static void main(String[] args) {
        // You can add more test cases here
        System.out.println(solution("101", "110").equals("11"));
        System.out.println(solution("111111", "10100").equals("83"));
        System.out.println(solution("111010101001001011", "100010101001").equals("242420"));
        System.out.println(solution("111010101001011", "10010101001").equals("31220"));
    }
}

队列

问题描述

给定一个长度为 nn 的序列 a1,a2,…,ana1​,a2​,…,an​,你可以选择删去其中最多 n−1n−1 个数,得到一个新序列 b1,b2,…,bmb1​,b2​,…,bm​ (1≤m≤n1≤m≤n),新序列保留原来的相对顺序。你的目标是删除某些数,使得新序列的第 ii 个数 bi=ibi​=i。现在需要求出最少删除多少个数才能得到这样的序列,如果无法得到,输出 −1−1。

例如,对于序列 [1, 4, 2, 3, 5],删除第 2 个和第 5 个元素后,可以得到序列 [1, 2, 3]

问题理解

我们需要从一个长度为 n 的序列 a 中删除一些元素,使得剩下的元素形成一个从 1 开始的连续递增序列。目标是找到最少需要删除多少个元素才能满足这个条件,如果无法形成这样的序列,则返回 -1

数据结构选择

由于我们只需要遍历一次序列,并且需要记录当前期望的值(即目标值),因此不需要额外的复杂数据结构。我们可以使用一个整数变量来记录当前期望的值,另一个整数变量来记录需要删除的元素数量。

算法步骤

  1. 初始化变量

    • target 表示当前期望的值,初始值为 1
    • deleteCount 表示需要删除的元素数量,初始值为 0
  2. 遍历序列

    • 对于序列中的每个元素 a[i],检查它是否等于 target
    • 如果 a[i] 等于 target,则说明当前元素符合要求,将 target 增加 1,表示下一个期望的值。
    • 如果 a[i] 不等于 target,则说明当前元素不符合要求,需要删除,因此 deleteCount 增加 1
  3. 判断结果

    • 遍历结束后,如果 target 仍然为 1,说明没有找到任何符合条件的元素,返回 -1
    • 否则,返回 deleteCount,表示最少需要删除的元素数量。

代码实现:

public class Main {
    public static int solution(int n, int[] a) {
        // write code here
        int target = 1; // 目标序列的起始值
        int deleteCount = 0; // 记录需要删除的数量

        for (int i = 0; i < n; i++) {
            if (a[i] == target) {
                target++; // 找到匹配的元素,目标值增加
            } else {
                deleteCount++; // 当前元素不匹配,需要删除
            }
        }

        // 如果没有找到任何符合条件的元素,返回 -1
        return target == 1 ? -1 : deleteCount; // placeholder return
    }

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

寻找满足条件的整数X

问题描述

小U 有四个正整数 ABC 和 D。你需要找到一个正整数 XX > 0),使得 A = B * X 且 C = D * X。如果不存在这样的 X,则返回 -1

解题思路

  1. 理解问题

    • 题目要求找到一个正整数 X,使得 A = B * X 且 C = D * X
    • 如果存在这样的 X,则返回 X;否则返回 -1
  2. 数据结构选择

    • 由于我们只需要处理整数运算,不需要额外的数据结构。
  3. 算法步骤

    • 第一步:检查 A 是否能被 B 整除。如果不能整除,则直接返回 -1,因为不存在这样的 X
    • 第二步:检查 C 是否能被 D 整除。如果不能整除,则直接返回 -1,因为不存在这样的 X
    • 第三步:计算 X1 = A / B 和 X2 = C / D
    • 第四步:比较 X1 和 X2。如果 X1 等于 X2,则返回 X1;否则返回 -1
  4. 代码实现

    • 代码中已经实现了上述逻辑,通过检查整除性、计算 X 的值并进行比较,最终返回结果。

代码实现

public class Main {
    public static int solution(int A, int B, int C, int D) {
        // write code here
        if (A % B != 0) {
            return -1;
        }

        // 检查 C 是否能被 D 整除
        if (C % D != 0) {
            return -1;
        }

        // 计算 X
        int X1 = A / B;
        int X2 = C / D;

        // 检查 X1 和 X2 是否相等
        if (X1 == X2) {
            return X1; // 返回满足条件的 X
        } else {
            return -1; // 不存在这样的 X
        }
    }

    public static void main(String[] args) {
        System.out.println(solution(4, 2, 6, 3) == 2);
        System.out.println(solution(8, 4, 15, 5) == -1);
        System.out.println(solution(9, 3, 12, 4) == 3);
    }
}