2785.将字符串中的元音字母排序

目标

给你一个下标从 0 开始的字符串 s ,将 s 中的元素重新 排列 得到新的字符串 t ,它满足:

  • 所有辅音字母都在原来的位置上。更正式的,如果满足 0 <= i < s.length 的下标 i 处的 s[i] 是个辅音字母,那么 t[i] = s[i] 。
  • 元音字母都必须以他们的 ASCII 值按 非递减 顺序排列。更正式的,对于满足 0 <= i < j < s.length 的下标 i 和 j ,如果 s[i] 和 s[j] 都是元音字母,那么 t[i] 的 ASCII 值不能大于 t[j] 的 ASCII 值。

请你返回结果字母串。

元音字母为 'a' ,'e' ,'i' ,'o' 和 'u' ,它们可能是小写字母也可能是大写字母,辅音字母是除了这 5 个字母以外的所有字母。

示例 1:

输入:s = "lEetcOde"
输出:"lEOtcede"
解释:'E' ,'O' 和 'e' 是 s 中的元音字母,'l' ,'t' ,'c' 和 'd' 是所有的辅音。将元音字母按照 ASCII 值排序,辅音字母留在原地。

示例 2:

输入:s = "lYmpH"
输出:"lYmpH"
解释:s 中没有元音字母(s 中都为辅音字母),所以我们返回 "lYmpH" 。

说明:

  • 1 <= s.length <= 10^5
  • s 只包含英语字母表中的 大写 和 小写 字母。

思路

有一个只包含英文字母的字符串,将其中的元音字母的位置按照 ASCII 码大小排序。

判断元音字母可以使用哈希表或者位运算。收集元音字母可以使用优先队列或者 StringBuilder 转成 charArray 之后再排序。

代码


/**
 * @date 2025-09-11 9:26
 */
public class SortVowels2785 {

    public static boolean[] isVowel = new boolean[26];

    static {
        isVowel[0] = true;
        isVowel['e' - 'a'] = true;
        isVowel['i' - 'a'] = true;
        isVowel['o' - 'a'] = true;
        isVowel['u' - 'a'] = true;
    }

    public String sortVowels(String s) {
        StringBuilder sb = new StringBuilder();
        char[] chars = s.toCharArray();
        for (char c : chars) {
            if (isVowel[Character.toLowerCase(c) - 'a']) {
                sb.append(c);
            }
        }
        char[] vowels = sb.toString().toCharArray();
        Arrays.sort(vowels);
        int j = 0;
        for (int i = 0; i < chars.length; i++) {
            if (isVowel[Character.toLowerCase(chars[i]) - 'a']) {
                chars[i] = vowels[j++];
            }
        }
        return new String(chars);
    }

}

性能

1317.将整数转换为两个无零整数的和

目标

「无零整数」是十进制表示中 不含任何 0 的正整数。

给你一个整数 n,请你返回一个 由两个整数组成的列表 [a, b],满足:

  • a 和 b 都是无零整数
  • a + b = n

题目数据保证至少有一个有效的解决方案。

如果存在多个有效解决方案,你可以返回其中任意一个。

示例 1:

输入:n = 2
输出:[1,1]
解释:a = 1, b = 1。a + b = n 并且 a 和 b 的十进制表示形式都不包含任何 0。

示例 2:

输入:n = 11
输出:[2,9]

示例 3:

输入:n = 10000
输出:[1,9999]

示例 4:

输入:n = 69
输出:[1,68]

示例 5:

输入:n = 1010
输出:[11,999]

说明:

2 <= n <= 10^4

思路

有一个大于 1 的整数 n,将其转换成不包含 0 的整数 ab,使得 a + b = n

从低位到高位遍历,如果数字 d 大于 1,拆分为 1d - 1,如果数字 d == 0 或 1 需要借位,拆分为 210 + d - 2。需要特别注意最高位是 1 的情况,直接将其加到其中一个数中即可。

代码


/**
 * @date 2025-09-08 8:50
 */
public class GetNoZeroIntegers1317 {

    public int[] getNoZeroIntegers(int n) {
        int a = 0, b = 0;
        int base = 1;
        while (n > 0) {
            int r = n % 10;
            n /= 10;
            if (r > 1) {
                a += base;
                b += (r - 1) * base;
            } else if (n == 0) {
                a += base;
            } else {
                r += 10;
                a += 2 * base;
                b += (r - 2) * base;
                n--;
            }
            base *= 10;
        }
        return new int[]{a, b};
    }

}

性能

1304.和为零的N个不同整数

目标

给你一个整数 n,请你返回 任意 一个由 n 个 各不相同 的整数组成的数组,并且这 n 个数相加和为 0 。

示例 1:

输入:n = 5
输出:[-7,-1,1,3,4]
解释:这些数组也是正确的 [-5,-1,1,2,3],[-3,-1,2,-2,4]。

示例 2:

输入:n = 3
输出:[-1,0,1]

示例 3:

输入:n = 1
输出:[0]

说明:

  • 1 <= n <= 1000

思路

构造 n 个不相同的数,使他们的和为 0。

一正一负,如果有剩余则为 0

代码


/**
 * @date 2025-09-07 19:10
 */
public class SumZero1304 {

    public int[] sumZero(int n) {
        int[] res = new int[n];
        for (int i = 0; i < n - 1; i += 2) {
            res[i] = i + 1;
            res[i + 1] = -i - 1;
        }
        return res;
    }
}

性能

3516.找到最近的人

目标

给你三个整数 x、y 和 z,表示数轴上三个人的位置:

  • x 是第 1 个人的位置。
  • y 是第 2 个人的位置。
  • z 是第 3 个人的位置,第 3 个人 不会移动 。

第 1 个人和第 2 个人以 相同 的速度向第 3 个人移动。

判断谁会 先 到达第 3 个人的位置:

  • 如果第 1 个人先到达,返回 1 。
  • 如果第 2 个人先到达,返回 2 。
  • 如果两个人同时到达,返回 0 。

根据上述规则返回结果。

示例 1:

输入: x = 2, y = 7, z = 4
输出: 1
解释:
第 1 个人在位置 2,到达第 3 个人(位置 4)需要 2 步。
第 2 个人在位置 7,到达第 3 个人需要 3 步。
由于第 1 个人先到达,所以输出为 1。

示例 2:

输入: x = 2, y = 5, z = 6
输出: 2
解释:
第 1 个人在位置 2,到达第 3 个人(位置 6)需要 4 步。
第 2 个人在位置 5,到达第 3 个人需要 1 步。
由于第 2 个人先到达,所以输出为 2。

示例 3:

输入: x = 1, y = 5, z = 3
输出: 0
解释:
第 1 个人在位置 1,到达第 3 个人(位置 3)需要 2 步。
第 2 个人在位置 5,到达第 3 个人需要 2 步。
由于两个人同时到达,所以输出为 0。

说明:

1 <= x, y, z <= 100

思路

有三个数 x y z,判断 xy 谁距离 z 最近,如果距离相同返回 0x 更近返回 1y 更近返回 2

代码


/**
 * @date 2025-09-04 8:44
 */
public class FindClosest3516 {

    public int findClosest(int x, int y, int z) {
        int dx = Math.abs(x - z);
        int dy = Math.abs(y - z);
        return dx == dy ? 0 : dx < dy ? 1 : 2;
    }
}

性能

3000.对角线最长的矩形的面积

目标

给你一个下标从 0 开始的二维整数数组 dimensions。

对于所有下标 i (0 <= i < dimensions.length),dimensions[i][0] 表示矩形 i 的长度,而 dimensions[i][1] 表示矩形 i 的宽度。

返回对角线最 长 的矩形的 面积 。如果存在多个对角线长度相同的矩形,返回面积最 大 的矩形的面积。

示例 1:

输入:dimensions = [[9,3],[8,6]]
输出:48
解释:
下标 = 0,长度 = 9,宽度 = 3。对角线长度 = sqrt(9 * 9 + 3 * 3) = sqrt(90) ≈ 9.487。
下标 = 1,长度 = 8,宽度 = 6。对角线长度 = sqrt(8 * 8 + 6 * 6) = sqrt(100) = 10。
因此,下标为 1 的矩形对角线更长,所以返回面积 = 8 * 6 = 48。

示例 2:

输入:dimensions = [[3,4],[4,3]]
输出:12
解释:两个矩形的对角线长度相同,为 5,所以最大面积 = 12。

说明:

  • 1 <= dimensions.length <= 100
  • dimensions[i].length == 2
  • 1 <= dimensions[i][0], dimensions[i][1] <= 100

思路

依题意模拟即可。

代码


/**
 * @date 2025-08-26 8:45
 */
public class AreaOfMaxDiagonal3000 {

    /**
     * 网友题解
     */
    class Solution {
        public int areaOfMaxDiagonal(int[][] dimensions) {
            int ans = 0, maxL = 0;
            for (int[] d : dimensions) {
                int x = d[0], y = d[1];
                int l = x * x + y * y;
                if (l > maxL || l == maxL && x * y > ans) {
                    maxL = l;
                    ans = x * y;
                }
            }
            return ans;
        }
    }

    /**
     * 执行通过
     */
    public int areaOfMaxDiagonal(int[][] dimensions) {
        int res = 0;
        int diagonal = 0;
        for (int[] dimension : dimensions) {
            int length = dimension[0];
            int width = dimension[1];
            int cur = length * length + width * width;
            if (diagonal < cur) {
                res = length * width;
                // 出错点:不要忘记更新 diagonal
                diagonal = cur;
            } else if (diagonal == cur) {
                // 出错点:对角线相等需要分开处理,取面积的最大值
                res = Math.max(res, length * width);
            }
        }
        return res;
    }

}

性能

1323.6和9组成的最大数字

目标

给你一个仅由数字 6 和 9 组成的正整数 num。

你最多只能翻转一位数字,将 6 变成 9,或者把 9 变成 6 。

请返回你可以得到的最大数字。

示例 1:

输入:num = 9669
输出:9969
解释:
改变第一位数字可以得到 6669 。
改变第二位数字可以得到 9969 。
改变第三位数字可以得到 9699 。
改变第四位数字可以得到 9666 。
其中最大的数字是 9969 。

示例 2:

输入:num = 9996
输出:9999
解释:将最后一位从 6 变到 9,其结果 9999 是最大的数。

示例 3:

输入:num = 9999
输出:9999
解释:无需改变就已经是最大的数字了。

说明:

  • 1 <= num <= 10^4
  • num 每一位上的数字都是 6 或者 9 。

思路

有一个由 69 组成的数字,可以最多将一个 6 变成 9,返回可以得到的最大数字。

将左边第一个 6 变为 9 得到的数字最大。

代码


/**
 * @date 2025-08-16 17:09
 */
public class Maximum69Number1323 {

    public int maximum69Number(int num) {
        int l = String.valueOf(num).length();
        int pow10 = (int) Math.pow(10, l - 1);
        int n = num;
        while (pow10 > 0) {
            if (n / pow10 == 6) {
                return num + 3 * pow10;
            }
            n -= 9 * pow10;
            pow10 /= 10;
        }
        return num;
    }

}

性能

342.4的幂

目标

给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。

整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4^x

示例 1:

输入:n = 16
输出:true

示例 2:

输入:n = 5
输出:false

示例 3:

输入:n = 1
输出:true

说明:

  • -2^31 <= n <= 2^31 - 1

进阶:你能不使用循环或者递归来完成本题吗?

思路

判断一个整数是否是 4 的幂。

参考 231.2的幂

负数的二进制表示中前导零的个数为 0,而 4 的幂的前导零个数为奇数,恰好排除掉了负数。

代码


/**
 * @date 2025-08-15 8:43
 */
public class IsPowerOfFour342 {

    public boolean isPowerOfFour(int n) {
        return (n & (n - 1)) == 0 && Integer.numberOfLeadingZeros(n) % 2 == 1;
    }

}

性能

326.3的幂

目标

给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true ;否则,返回 false 。

整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3^x

示例 1:

输入:n = 27
输出:true

示例 2:

输入:n = 0
输出:false

示例 3:

输入:n = 9
输出:true

示例 4:

输入:n = 45
输出:false

说明:

  • -2^31 <= n <= 2^31 - 1

进阶:你能不使用循环或者递归来完成本题吗?

思路

判断给定整数 n 是否是 3 的幂。

进阶解法是判断是否为最大的 3 的幂的约数,Integer 范围内最大的 3 的幂为 3^19 = 1162261467,如果 n3 的幂那么一定可以被它整除。

代码


/**
 * @date 2025-08-13 8:40
 */
public class IsPowerOfThree326 {

    public boolean isPowerOfThree(int n) {
        int base = 3;
        long num = 1;
        while (num <= n) {
            if (num == n) {
                return true;
            }
            num *= base;
        }
        return false;
    }

}

性能

231.2的幂

目标

给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。

如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。

示例 1:

输入:n = 1
输出:true
解释:20 = 1

示例 2:

输入:n = 16
输出:true
解释:24 = 16

示例 3:

输入:n = 3
输出:false

提示:

  • -2^31 <= n <= 2^31 - 1

进阶:你能够不使用循环/递归解决此问题吗?

思路

判断数字是不是 2 的幂。

提前预处理 2 的幂。

进阶做法是判断 n & (n - 1) == 0

代码


/**
 * @date 2025-08-09 20:33
 */
public class IsPowerOfTwo231 {

    static Set<Integer> set = new HashSet<>();

    static {
        for (int i = 0; i < 31; i++) {
            set.add(1 << i);
        }
    }

    public boolean isPowerOfTwo(int n) {
        return set.contains(n);
    }

}

性能

3477.水果成篮II

目标

给你两个长度为 n 的整数数组,fruits 和 baskets,其中 fruits[i] 表示第 i 种水果的 数量,baskets[j] 表示第 j 个篮子的 容量。

你需要对 fruits 数组从左到右按照以下规则放置水果:

  • 每种水果必须放入第一个 容量大于等于 该水果数量的 最左侧可用篮子 中。
  • 每个篮子只能装 一种 水果。
  • 如果一种水果 无法放入 任何篮子,它将保持 未放置。

返回所有可能分配完成后,剩余未放置的水果种类的数量。

示例 1

输入: fruits = [4,2,5], baskets = [3,5,4]
输出: 1
解释:
fruits[0] = 4 放入 baskets[1] = 5。
fruits[1] = 2 放入 baskets[0] = 3。
fruits[2] = 5 无法放入 baskets[2] = 4。
由于有一种水果未放置,我们返回 1。

示例 2

输入: fruits = [3,6,1], baskets = [6,4,7]
输出: 0
解释:
fruits[0] = 3 放入 baskets[0] = 6。
fruits[1] = 6 无法放入 baskets[1] = 4(容量不足),但可以放入下一个可用的篮子 baskets[2] = 7。
fruits[2] = 1 放入 baskets[1] = 4。
由于所有水果都已成功放置,我们返回 0。

说明:

  • n == fruits.length == baskets.length
  • 1 <= n <= 100
  • 1 <= fruits[i], baskets[i] <= 1000

思路

有一个数组 basketsfruits,从左到右遍历 fruits,并删除 baskets 中第一个大于等于 fruits[i] 的元素,返回 baskets 最后剩余元素个数。

依题意模拟。

代码


/**
 * @date 2025-08-05 9:10
 */
public class NumOfUnplacedFruits3477 {

    public int numOfUnplacedFruits(int[] fruits, int[] baskets) {
        int n = fruits.length;
        int res = n;
        for (int fruit : fruits) {
            for (int i = 0; i < n; i++) {
                if (baskets[i] >= fruit){
                    res--;
                    baskets[i] = 0;
                    break;
                }
            }
        }
        return res;
    }

}

性能