【2024】【字节青训营】:字节青训营入营测试题——Java版本(已提交通过)

目录

简单题目

计算x到y的最小步数

环状 DNA 序列的最小表示法

Base32 解码和编码

打点计时器

兔群繁殖之谜

完美整数

找出整数数组中占比超过 一半 的数

找出最长的神奇数列

找单独的数

字符串最短循环字串

二进制反码转换问题

中等题目

简单四则运算

数字翻译成字符串有多少种可能性

最大异或和计算

五子棋获胜策略

困难题目

二进制之和

查找热点数据



要求:

简单题不少于10道题

中等题目不少于4道题

困难题目不少于1道题

介绍:

本次24青训营,入营和之前的考核模型有所不同,之前是做题,几十个选择题,两道算法题,一道简答题,现在则是在ai的辅助下进行刷题考核,这么做的原因无非是推广自己家的智能编码助手,还有就是此次代码考核在在线平台上,就能得到大量的数据,然后使用这些数据去强化编码助手,最后就是ai助手有点傻,一个是你把他给你的代码,都过不了示例,然后他容易顺着你代码的想法,往后推理,如果你一开始的想法不对,就会进入死角。

简单题目

已完成 11 成功提交 10

兔群繁殖之谜样例通过,提交失败

计算x到y的最小步数

# 问题描述AB 实验同学每天都很苦恼如何可以更好地进行 AB 实验,每一步的流程很重要,我们目标为了缩短所需的步数。我们假设每一步对应到每一个位置。从一个整数位置 `x` 走到另外一个整数位置 `y`,每一步的长度是正整数,每步的值等于上一步的值 `-1`, `+0`,`+1`。求 `x` 到 `y` 最少走几步。并且第一步必须是 `1`,最后一步必须是 `1`,从 `x` 到 `y` 最少需要多少步。## 样例说明- 整数位置 `x` 为 `12`,另外一个整数位置 `y` 为 `6`,我们需要从 `x` 走到 `y`,最小的步数为:`1`,`2`,`2`,`1`,所以我们需要走 `4` 步。
- 整数位置 `x` 为 `34`,另外一个整数位置 `y` 为 `45`,我们需要从 `x` 走到 `y`,最小的步数为:`1`,`2`,`3`,`2`,`2`,`1`,所以我们需要走 `6` 步。
- 整数位置 `x` 为 `50`,另外一个整数位置 `y` 为 `30`,我们需要从 `x` 走到 `y`,最小的步数为:`1`,`2`,`3`,`4`,`4`,`3`,`2`,`1`,所以我们需要走 `8` 步。## 输入格式输入包含 `2` 个整数 `x`,`y`。(`0<=x<=y<2^31`)## 输出格式对于每一组数据,输出一行,仅包含一个整数,从 `x` 到 `y` 所需最小步数。## 输入样例```
12 6
34 45
50 30
```## 输出样例```
4
6
8
```

问题分析:

从x走到y,其实就是从步伐大小从1开始走,最后一步也必须为1,每一步之间呢,可以+1,0,和-1,如果说想要最小步数,这个步伐肯定要迈的大,我的代码呢,遵循一个原则,就是第一步肯定为1,接下来每一步有三种选择,假设步伐为x,一个是x + 1,一个是x,一个是x - 1,在优先级上x + 1 > x > x - 1,在是否合规上采取走下一步的时候,必须保证剩余的距离,可以降到 1 ,也就是说先 x + 1,但是剩下的距离必须大于等于 x~1的和,如果不可以那就尝试 x,剩下的距离大于等于 x - 1 ~ 1 的he,x - 1也是如此,直至走到y。

代码如下:

public class Main {public static int sum(int x) {if (x <= 0) {return 0;}int res = 0;for (int i = 1; i <= x; i++) {res += i;}return res;}// Calculate the minimum steps from x to ypublic static int solution(int x, int y) {if (x > y) {int temp = x;x = y;y = temp;}int l = 0, r = y - x;int step = 0;int stepDistance = 0;while (l < r) {if (step == 0) {stepDistance = 1;step = 1;l += stepDistance;continue;}int step1 = stepDistance + 1;int step2 = stepDistance;int step3 = stepDistance - 1;if (l + step1 < r) {int m = l + step1;int s = sum(step1 - 1);if ((r - m) >= s) {l = m;step++;stepDistance = step1;continue;}}if (l + step2 <= r) {int m = l + step2;int s = sum(step2 - 1);if ((r - m) >= s) {l = m;step++;stepDistance = step2;continue;}}if (l + step3 <= r) {int m = l + step3;int s = sum(step3 - 1);if ((r - m) >= s) {l = m;step++;stepDistance = step3;continue;}}}return step;}public static void main(String[] args) {// Add your test cases hereSystem.out.println(solution(6, 7) == 1);      // Should print trueSystem.out.println(solution(12, 6) == 4);     // Should print trueSystem.out.println(solution(34, 45) == 6);    // Should print trueSystem.out.println(solution(50, 30) == 8);     // Should print true}
}

运行结果:

环状 DNA 序列的最小表示法

# 问题描述环状 DNA 又称超螺旋,即一段碱基序列呈现环状,在分析时,需要将相同序列的环状 DNA 分到相同组内,现需将环状碱基序列按照最小表示法进行排序。一段长度为 `n` 的碱基序列,按照顺时针方向,碱基序列可以从任意位置起开始该序列顺序,因此长度为 `n` 的碱基序列有 `n` 种表示法。例如:长度为 6 的碱基序列 `CGAGTC`,有 `CGAGTC`、`GAGTCC`、`AGTCCG` 等表示法。在这些表示法中,字典序最小的称为“最小表示”。输入一个长度为 `n`(`n <= 100`)的环状碱基序列(只包含 `A`、`C`、`G`、`T` 这 4 种碱基)的一种表示法,输出该环状碱基序列的最小表示。例如:
`ATCA` 的最小表示是 `AATC`
`CGAGTC` 的最小表示是 `AGTCCG`## 输入描述一段 DNA 碱基序列## 输出描述DNA 碱基序列的最小表示**备注**:
`n <= 100`
DNA 由大写英文字母 `A`、`G`、`C`、`T` 组成**示例 1**
输入:`ATCA`
输出:`AATC`**示例 2**
输入:`CGAGTC`
输出:`AGTCCG`

问题分析:

通过循环将所有的可能存储起来,然后循环比较得出最小的DNA碱基序列

代码如下:

import java.util.ArrayList;
import java.util.List;public class Main {public static String solution(String dna_sequence) {// Create a list to hold the different representations of the DNA sequenceList<String> representations = new ArrayList<>();int length = dna_sequence.length();// Generate all rotations of the DNA sequencefor (int i = 0; i < length; i++) {String representation = dna_sequence.substring(i) + dna_sequence.substring(0, i);representations.add(representation);}// Find the minimum representationString minRepresentation = representations.get(0);for (String representation : representations) {if (representation.compareTo(minRepresentation) < 0) {minRepresentation = representation;}}return minRepresentation;}public static void main(String[] args) {// Add your test cases hereSystem.out.println(solution("ATCA").equals("AATC")); // Should print trueSystem.out.println(solution("CGAGTC").equals("AGTCCG")); // Should print trueSystem.out.println(solution("TCATGGAGTGCTCCTGGAGGCTGAGTCCATCTCCAGTAG").equals("AGGCTGAGTCCATCTCCAGTAGTCATGGAGTGCTCCTGG")); // Should print true}
}

运行结果:

Base32 解码和编码

# 问题描述你需要实现一个 Base32 的编码和解码函数。相比于 Base32,你可能更熟悉 Base64,Base64 是非常常见的用字符串形式表示二进制数据的方式,在邮件附件、Web 中的图片中都有广泛的应用。Base32 是 Base64 的变种,与 Base64 不同的地方在于 Base64 以 6 bit 为一组作为索引,而 Base32 以 5 bit 为一组作为索引,每一组用一个 ASCII 字符表示。Base 64 总共需要 64 个字符表示,而 Base32 则只需要 32 个字符表示。Base32 的编码流程如下:
- 对二进制数据进行预处理:如果二进制数据的 bit 数目不不是 5 的倍数的话,在末尾补 0 直至为 5 的倍数
- 以 5 bit 为一组进行分组
- 将每一组的 5 bit 二进制转换为索引(0 - 31)
- 在索引 - 字符转换表中查询索引对应的字符
- 根据原始二进制数据的 bit 数目除以 40 后的余数,确定末尾需要补 0 的数目- 如果原始二进制数据 bit 数目除以 40 后的余数是 0 的话,不需要补 +- 如果原始二进制数据 bit 数目除以 40 后的余数是 8 的话,补 6 个 +- 如果原始二进制数据 bit 数目除以 40 后的余数是 16 的话,补 4 个 +- 如果原始二进制数据 bit 数目除以 40 后的余数是 24 的话,补 3 个 +- 如果原始二进制数据 bit 数目除以 40 后的余数是 32 的话,补 1 个 +Base32 的索引 - 字符转换表见下方。索引:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31字符:9 8 7 6 5 4 3 2 1 0 m  n  b  v  c  x  z  a  s  d  f  g  h  j  k  l  p  o  i  u  y  t**示例****编码**- 输入:字符串 `foo`
- 字符 `f` 的 ASCII 编号为 102,字符 `o` 的 ASCII 编号为 111
- 将字符串 `foo` 以 ASCII 编号形式表达为 102 111 111 的序列
- 将 102 111 111 的序列转换为二进制表示,即 01100110 01101111 01101111,将二进制字符串以 40 个为一组进行分割
- 最后一组的二进制字符串长度为 24,不是 5 的倍数,因此在最后补 0,直至其能被 5 整除(在此例子中,补 1 个即可),二进制字符串表示为: 01100110 01101111 01101111 0
- 每 5 bit 为一组,表示为:01100 11001 10111 10110 11110
- 将每一组转换为十进制的索引,表示为:12 25 23 22 30,对应字符 `b` `l` `j` `h` `y`
- 由于最终输出字符串长度不是 8 的倍数,在输出最后补充 3 个 `+`
- 查询索引 - 字符转换表后,可以得出最终的输出为:`bljhy+++``Input data: foo`
`Input in Unicode: 102 111 111`
`Unicode in binary (8-bit): 01100110 01101111 01101111 0`
`Unicode in binary (5-bit): 01100 11001 10111 10110 11110`
`Decimal: 12 25 23 22 30`
`Pad: + + +`
`Output: b l j h y + + +`**解码**- 输入:`bljhy+++`
- 查询索引 - 字符转换表后,可知原始的二进制数据组为:01100 11001 10111 10110 11110
- 由末尾 3 个 `+` 可知在编码时原始二进制数据最后一组的个数为 24 个,由此可知最后一组数据为:01100110 01101111 01101111
- 将二进制数据转换为 ASCII 编号后可知,原始字符串的 Unicode 序列为:102 111 111
- 将 Unicode 序列转换为字符串,即可得出原始字符串,为:`foo`**输入示例**`foo`
`b0zj5+++`- 第一行为需要编码的原始字符串:`rawStr`
- 第二行为需要解码的 Base32 字符串:`encodedStr`**输出示例**`bljhy+++`
`bar`**解释**:
- 第一行编码后的输出为 `bljhy+++`
- 第二行解码后的输出为 `bar`**数据范围**`rawStr[n]` 为 ASCII 的可显示字符,`rawStr.length < 2048`
`encodedStr` 为使用此算法编码后的 Base32 字符序列,`encodedStr.length < 4096`

问题分析:

这个题目不是很难,但是很繁琐,可能是我的实现问题的原因,我写了很多函数,

各个函数的作用:

`decimalToBinary8Bits` 用于将十进制数转换为 8 位二进制字符串,

`binaryToDecimal` 用于将二进制字符串按 5 位一组转换为十进制数并存入向量,

`decimalArrayToBinary` 用于将十进制数向量转换为二进制字符串,

`binaryToChar` 用于将二进制字符串按 8 位一组转换为 ASCII 码对应的字符。

`jiema` 函数用于解码操作,通过判断输入字符串末尾的 `+` 个数来确定原始二进制数据的长度,然后进行解码处理。但这个函数中的条件判断较多,可能会增加理解和维护的难度。

`solution` 函数是主要的处理函数,它对输入的原始字符串进行预处理,转换为二进制字符串并根据余数进行补零,然后进行编码和解码操作。

代码如下:

import java.util.ArrayList;
import java.util.List;public class Main {static char[] base32 = {'9', '8', '7', '6', '5', '4', '3', '2', '1', '0', 'm', 'n', 'b', 'v', 'c', 'x', 'z', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'p', 'o', 'i', 'u', 'y', 't'};public static String decimalToBinary8Bits(int num) {StringBuilder binary = new StringBuilder();for (int i = 7; i >= 0; i--) {binary.append((num & (1 << i)) != 0 ? '1' : '0');}return binary.toString();}public static List<Integer> binaryToDecimal(String binaryStr) {List<Integer> decimalNums = new ArrayList<>();for (int i = 0; i < binaryStr.length(); i += 5) {String group = binaryStr.substring(i, Math.min(i + 5, binaryStr.length()));int decimal = 0;for (char c : group.toCharArray()) {decimal = decimal * 2 + (c - '0');}decimalNums.add(decimal);}return decimalNums;}public static String decimalArrayToBinary(List<Integer> arr) {StringBuilder result = new StringBuilder();for (int num : arr) {StringBuilder binary = new StringBuilder();for (int i = 4; i >= 0; i--) {binary.append((num & (1 << i)) != 0 ? '1' : '0');}result.append(binary);}return result.toString();}public static String binaryToChar(String binaryStr) {StringBuilder result = new StringBuilder();for (int i = 0; i < binaryStr.length(); i += 8) {String group = binaryStr.substring(i, Math.min(i + 8, binaryStr.length()));int decimal = 0;for (char c : group.toCharArray()) {decimal = decimal * 2 + (c - '0');}result.append((char) decimal);}return result.toString();}public static String jiema(String encodedStr) {int i;for (i = encodedStr.length() - 1; i > 0 && encodedStr.charAt(i) == '+'; i--);String newstr = encodedStr.substring(0, i + 1);List<Integer> st2 = new ArrayList<>();for (char c : newstr.toCharArray()) {for (int j = 0; j < base32.length; j++) {if (c == base32[j]) {st2.add(j);}}}String newnewstr = decimalArrayToBinary(st2);String res2 = "";if (newnewstr.length() % 40 == 10) {String newstrs = newnewstr.substring(0, newnewstr.length() - 2);res2 = binaryToChar(newstrs);} else if (newnewstr.length() % 40 == 20) {String newstrs = newnewstr.substring(0, newnewstr.length() - 4);res2 = binaryToChar(newstrs);} else if (newnewstr.length() % 40 == 25) {String newstrs = newnewstr.substring(0, newnewstr.length() - 1);res2 = binaryToChar(newstrs);} else if (newnewstr.length() % 40 == 35) {String newstrs = newnewstr.substring(0, newnewstr.length() - 3);res2 = binaryToChar(newstrs);}return res2;}public static String solution(String rawStr, String encodedStr) {List<Integer> st = new ArrayList<>();StringBuilder str1 = new StringBuilder();for (char c : rawStr.toCharArray()) {str1.append(decimalToBinary8Bits(c));}int r = str1.length() % 40;if (r == 8) {str1.append("00");} else if (r == 16) {str1.append("0000");} else if (r == 24) {str1.append("0");} else if (r == 32) {str1.append("000");}st = binaryToDecimal(str1.toString());StringBuilder res1 = new StringBuilder();for (int value : st) {res1.append(base32[value]);}while (res1.length() % 8 != 0) {res1.append("+");}StringBuilder res2 = new StringBuilder();for (int i = 0; i < encodedStr.length(); i += 8) {res2.append(jiema(encodedStr.substring(i, Math.min(i + 8, encodedStr.length()))));}return res1.toString() + ":" + res2.toString();}public static void main(String[] args) {// You can add more test cases hereSystem.out.print(solution("foo", "b0zj5+++"));System.out.println(solution("foo", "b0zj5+++").equals("bljhy+++:bar")); // Should print trueSystem.out.println(solution("The encoding process represents 40-bit groups of input bits as output strings of 8 encoded characters.  Proceeding from left to right, a 40-bit input group is formed by concatenating 5 8bit input groups. These 40 bits are then treated as 8 concatenated 5-bit groups, each of which is translated into a single character in the base 32 alphabet.  When a bit stream is encoded via the base 32 encoding, the bit stream must be presumed to be ordered with the most-significant-bit first. That is, the first bit in the stream will be the high-order bit in the first 8bit byte, the eighth bit will be the low-order bit in the first 8bit byte, and so on.", "bljhy+++b0zj5+++").equals("maf3m164vlahyl60vlds9i6svuahmiod58l3mi6sbglhmodfcbz61b8vb0fj1162c0jjmi6d58jhb160vlk2mu89b0fj1il9b4ls9oogcak2mu89cvp25pncbuls9oo359i79lncbvjh1ln558ahzknsb4aj1lnscbj7917zc0jh3ln4bafhill9bll3yo09vashbu89cajs9id0buf21n89b5z61b8vb0fj1160vlk2mu89bul3yunz58fj3163vul3pln558a2s166vuj33knfbgj37u60vlds9v0928a3su89v4j29unf58dj5oogc8lsi17fv8sj3l093zk79kd0cals9knsbfz21p64vkz21id4b4p3ml89b4ls9c89bvjhiko8cashiknfbgs79v0vb0fj1162c0jjmi6d4zz3mkn6v9z3yla9cuf3sko158fj316fc0zhiiobb4p3ml89v4j21ol9b5z23pncbuh3m166v8zj5kn6casj5160vkz21p6458a37io459ld5168vak3zkn7bgp7i189muf3moa9b5z35pnf58lj1id4b4hs9pnd58shikoxbash116hv4zs9u61bfz35kndbfz63ba9bgj33oo5v4j3cn89caf3m167v4p79iofc0sh7o09vgpj3u89b0ss9i6sbgljmon4bzz21ol9b0ss9oosbasj5ln558ohsu6158p3zl09vgjj3u8vcvfhcod0blfh3kncczhs9kd0czz3bpnscvp7i17fv8zj1160cbh79u61bfz3bpnscvp79kd0czz3soa9caf3m16dcal3mknv58ohso6b58a3m16fv8ss9p60buf7p16xc0s3mia9b0fj1160vkz21p6458d3siddczz6zkd0czz35ynfbfh79u61bfz3mpn2v8p3z167v4p79uo0vah79kd458p3zl09vajjcn09vul31lns58a3su89v4j79u61bfz3bpnscvp79c67v4p79kdlcassk168vls79iox58jhinz+:foobar")); // Should print true}
}

运行结果:

打点计时器

# 问题描述小明想发明一台打点计数器,这个计数器有这样的一个功能:- 它可以接收一个递增的数据范围(形如[3, 9]),其中第一个数字代表起始,第二个数字代表结束- 这个数据范围中包含几个数字,打点计数器就会打几个点- 在传入的多组数据范围中,如果出现了范围的重复,机器则不会重复打点你可以帮助小明算一算,在不同的情况下,计数器会打出几个点么?## 输入格式一个二维数组## 输出格式一个整数,表达在输入是这个数组的情况下,计数器打出的点数**输入样例(1)**[[1,4],[7, 10],[3, 5]
]**输出样例(1)**7**输入样例(2)**[[1,2],[6, 10],[11, 15]
]**输出样例(2)**9**数据范围**- 数字范围 [-10^9, 10^9],数组长度 < 2^16

问题分析:

本题目采用集合来处理,因为集合具有互异性,所以在打点过程中重复区域的会被去掉,遍历每段区间,区间遍历每个点,存进集合中,最后返回集合的大小就是打点的数量

代码如下:

import java.util.HashSet;
import java.util.Set;public class Main {public static int solution(int[][] inputArray) {// Create a set to store unique integersSet<Integer> mySet = new HashSet<>();// Iterate through the input rangesfor (int[] range : inputArray) {int start = range[0];int end = range[1];for (int i = start; i < end; i++) {mySet.add(i); // Add each integer in the range to the set}}return mySet.size(); // Return the size of the set which represents the unique integers}public static void main(String[] args) {// Add your test cases hereint[][] testArray1 = {{1, 4}, {7, 10}, {3, 5}};int[][] testArray2 = {{1, 2}, {6, 10}, {11, 15}};System.out.println(solution(testArray1) == 7); // Should print trueSystem.out.println(solution(testArray2) == 9); // Should print true}
}

运行结果:

兔群繁殖之谜

# 问题描述
- 如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第 `n` 个月能繁殖成多少对兔子?(举例,第1个月是1对兔子,第2个月是2对兔子)## 输入格式
- 数字## 输出格式
- 数字## 输入样例
- 5## 输出样例
- 8## 数据范围
- `[1, 75]`## 测试数据集- 样例1- 输入:`5`- 输出:`8`- 样例2- 输入:`1`- 输出:`1`- 样例3- 输入:`15`- 输出:`987`- 样例4- 输入:`50`- 输出:`20365011074`

问题分析:

  1. 函数定义:
    • int solution(int n):这个函数接受一个整数 n 作为输入,并返回第 n 个月兔子的对数。
  1. 基本情况处理:
    • 如果 n 是 1 或 2,函数直接返回 1 或 2,这是斐波那契数列的前两个数(或在这个问题中,第一个月和第二个月的兔子对数)。
  1. 动态规划数组:
    • vector<int> dp(n + 1):创建了一个大小为 n + 1 的动态规划数组 dp,用于存储从第 1 个月到第 n 个月的兔子对数。
    • dp[1] = 1dp[2] = 2:初始化前两个月的兔子对数。
  1. 递推公式:
    • for (int i = 3; i <= n; i++):从第 3 个月开始,使用递推公式 dp[i] = dp[i - 1] + dp[i - 2] 计算每个月的兔子对数。这个公式基于斐波那契数列的定义,即每个数都是前两个数的和。
  1. 返回结果:
    • return dp[n]:返回第 n 个月的兔子对数

代码如下:

public class Main {  public static long solution(int n) {  // 使用动态规划来保存前两个月的兔子对数  if (n == 1) return 1; // 第一个月  if (n == 2) return 2; // 第二个月  long[] dp = new long[n + 1]; // dp[i] 表示第 i 个月的兔子对数  dp[1] = 1; // 第一个月  dp[2] = 2; // 第二个月  // 计算每个月的兔子对数  for (int i = 3; i <= n; i++) {  dp[i] = dp[i - 1] + dp[i - 2]; // 递推公式  }  return dp[n]; // 返回第 n 个月的兔子对数  }  public static void main(String[] args) {  // 验证输出结果是否符合预期  System.out.println(solution(5) == 8);  System.out.println(solution(1) == 1);  System.out.println(solution(15) == 987);  System.out.println(solution(50) == 20365011074L); // 注意:Java中整数有范围限制,这里需要处理大数  }  
}

运行结果:

测试通过

提交失败! 可以尝试改为python

完美整数

# 问题描述
一个整数如果由相同数字构成,可以称为完美整数;比如说1、11、333就是完美整数,12、19、101就是不完美的整数。
现在想知道,在区间 `[x, y]` 中有多少个整数是完美整数。## 输入格式
每个样例有一行,是整数 `x` 和 `y`;(1 ≤ x ≤ y ≤ 10^9)## 输出格式
每一个样例一行,是整数 `m`,表示区间 `[x, y]` 中有 m 个整数是完美整数。## 输入样例1
1 10  ## 输出样例19  ## 输入样例2
2 22## 输出样例2
10## 数据范围1 ≤ t ≤ 1000
1 ≤ x ≤ y ≤ 10^9

问题分析:

其实生成了10^9之内的所有完美整数,然后对这些完美整数进行排序,然后计算完美整数的左右区间,通过区间得到完美整数的数量

代码如下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class Main {// Generate all perfect numbers not exceeding 10^9public static List<Integer> generatePerfectNumbers() {List<Integer> perfectNumbers = new ArrayList<>();for (int digit = 1; digit <= 9; digit++) {  // From 1 to 9int perfectNumber = digit; // Use int instead of longwhile (perfectNumber <= 1000000000) {  // Build perfect numbers by concatenatingperfectNumbers.add(perfectNumber);if (perfectNumber > 1000000000 / 10) break; // Prevent overflow when multiplying by 10perfectNumber = perfectNumber * 10 + digit;}}return perfectNumbers;}// Precompute perfect numbersstatic List<Integer> perfectNumbers = generatePerfectNumbers();public static int solution(int x, int y) {Collections.sort(perfectNumbers); // Sort perfect numbersint leftIndex = lowerBound(perfectNumbers, x);  // Find first position >= xint rightIndex = upperBound(perfectNumbers, y);  // Find first position > y// Count of perfect numbers in the rangereturn rightIndex - leftIndex;  }public static int lowerBound(List<Integer> arr, int key) {int left = 0, right = arr.size();while (left < right) {int mid = left + (right - left) / 2;if (arr.get(mid) < key) {left = mid + 1;} else {right = mid; // Include mid if it's equal}}return left;}public static int upperBound(List<Integer> arr, int key) {int left = 0, right = arr.size();while (left < right) {int mid = left + (right - left) / 2;if (arr.get(mid) <= key) { // Increment for equal valuesleft = mid + 1;} else {right = mid;}}return left;}public static void main(String[] args) {System.out.println(solution(1, 10) == 9); // Should print trueSystem.out.println(solution(2, 22) == 10); // Should print true}
}

运行结果:

找出整数数组中占比超过 一半 的数

## 问题描述
- 给定一个长度为n的整型数组,已知其中一个数字的出现次数超过数组长度的一半,找出这个元素## 输入格式
- 一个长度为n的数组,其中某个元素的出现次数大于n/2## 输出格式
- 一个整数## 输入样例
- [1,3,8,2,3,1,3,3,3]## 输出样例
- 3## 数据范围
- 任意长度为n整数数组,其中某个元素的出现次数大于n/2

问题分析:

其实就是找出出现次数超过一半的数,首先通过快排将数组拍成有序的,然后取有序的中间那个数就可以,因为是大于一半的,就算是极限情况从头或者从尾开始,中间那个数也是出现一半以上的,更不用说其他在中间的情况了

代码如下:

import java.util.Arrays;public class Main {// Correct quick sort functionpublic static void quickSort(int l, int r, int[] num) {if (l >= r) return;int mid = num[(l + r) / 2]; // Choose pivot elementint i = l - 1, j = r + 1;while (i < j) {do i++; while (num[i] < mid);do j--; while (num[j] > mid);if (i < j) {// Swap elementsint temp = num[i];num[i] = num[j];num[j] = temp;}}quickSort(l, j, num);quickSort(j + 1, r, num);}// Modified solution function, returning the element that appears more than half the timepublic static int solution(int[] list) {quickSort(0, list.length - 1, list);return list[(list.length - 1) / 2]; // Return the median element}public static void main(String[] args) {// Test casesSystem.out.println(solution(new int[]{1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3); // Should print true}
}

运行结果:

找出最长的神奇数列

# 问题描述小明是一个中学生,今天他刚刚学习了数列。他在纸上写了一个长度为 `n` 的正整数序列,$a_0,a_1,\ldots,a_{n-1}$。这个数列里面只有 1 和 0,我们将 1 和 0 没有重复跟随并且至少由 3 个数组成的数列的数列称之为「神奇数列」。比如 `10101` 是一个神奇数列,`1011` 不是一个神奇数列。他想知道这个序列里面最长的「神奇数列」是哪个,你可以帮帮他吗?## 输入格式- 一行连续的数 `s`,只有 `0` 和 `1`## 输出格式- 一行数## 输入样例0101011101## 输出样例010101## 数据范围- $1 < s.length \leq 5 \times 10^4$

问题分析:

通过遍历字符串,如果相邻的不同,就长度增加,如果相同了,就把相同之前的不同的一个串尝试更新的最长神奇数列,首先要长度大于3,其次要和之前的生气数列比较,最后返回字符串

代码如下:

public class Main {public static String solution(String inp) {String maxList = ""; // To store the longest magical sequenceint maxLength = 0; // Length of the longest magical sequenceint n = inp.length(); // Length of the input string// Current magical sequence's starting position and lengthint start = 0;int currentLength = 1;for (int i = 1; i < n; i++) {if (inp.charAt(i) != inp.charAt(i - 1)) { // Current character differs from previous charactercurrentLength++; // Update the length of the current magical sequence} else {// Check if the current length is at least 3, and update if necessaryif (currentLength >= 3) {String candidate = inp.substring(start, i);if (currentLength > maxLength) {maxLength = currentLength;maxList = candidate; // Update the longest magical sequence}}// Reset the current magical sequencestart = i;currentLength = 1; // Reset counting}}// Handle the last segment of the magical sequenceif (currentLength >= 3) {String candidate = inp.substring(start, n);if (currentLength > maxLength) {maxList = candidate; // Update the longest magical sequence}}return maxList; // Return the longest magical sequence}public static void main(String[] args) {// Add your test cases hereSystem.out.println(solution("0101011101").equals("010101")); // Should print true}
}

运行结果:

找单独的数

# 问题描述
有一堆数字,除了一个数字,其它的数字都是成对出现。班上的每个同学拿一个数字,正好将这些数字全部拿完,问如何快速找到拿了单独数字的同学?## 输入格式
- 空格分隔输入所有的数字## 输出格式
- 单独的那个数字## 输入样例(1)
```
1 1 2 2 3 3 4 5 5
```
## 输出样例(1)
4## 输入样例(2)
```
0 1 0 1 2
```
## 输出样例(2)
2

问题分析:

这个应该是100个题目中最简单的一个了,通过异或会把相同的数字抵消掉,剩下的就是那个单独的数字。

代码如下:


public class Main {public static int solution(int[] inp) {// Edit your code hereint res = 0;for (int num : inp) {res ^= num;}return res;}public static void main(String[] args) {// Add your test cases hereSystem.out.println(solution(new int[]{1, 1, 2, 2, 3, 3, 4, 5, 5}) == 4);System.out.println(solution(new int[]{0, 1, 0, 1, 2}) == 2);}
}

提交结果:

字符串最短循环字串

# 问题描述
- 输入一个字符串,判断其是否完全循环,若是循环的,输出最短的循环子串,否则输出空`""`
- 如输入 `abababab`,输出 `ab`;输入 `ab` 则输出 `""`## 输入格式
- 合法字符串 如 `abcabcabcabc` `aaa`## 输出格式
- 最短的循环子串 `"abc"` `"a"`## 输入样例
- `"abcabcabcabc"`## 输出样例
- `"abc"`## 数据范围
测试数据集

问题分析:

首先将每一种可能的字符串切出来,然后通过循环比较,字串通过取余循环,来判断是否为循环字串,如果j走到了最后,那么当前的字串就是他的循环字串,因为是从小的串开始,如果j走到了最后那么就不会切更大的字串直接跳出循环,保证了是最小的字串,如果i走到最后还没有找到,那么结果就是“”。

代码如下:

public class Main {public static String solution(String inp) {int n = inp.length();for (int len = 1; len <= n / 2; len++) { // Check lengths from 1 to n / 2if (n % len == 0) { // Only consider lengths that divide the string length evenlyString substring = inp.substring(0, len); // Get the potential repeating substringStringBuilder sb = new StringBuilder();// Build the string from repeating the substringfor (int j = 0; j < n / len; j++) {sb.append(substring);}// Check if the built string is equal to the original stringif (sb.toString().equals(inp)) {return substring; // Found the repeating substring}}}return ""; // If no substring found, return empty string}public static void main(String[] args) {// Add your test cases hereSystem.out.println(solution("abcabcabcabc").equals("abc")); // Should print trueSystem.out.println(solution("aaa").equals("a")); // Should print trueSystem.out.println(solution("abababab").equals("ab")); // Should print trueSystem.out.println(solution("ab").equals("")); // Should print trueSystem.out.println(solution("abcdabcdabcdabcd").equals("abcd")); // Should print trueSystem.out.println(solution("b").equals("")); // Should print true}
}

提交结果:

二进制反码转换问题

# 二进制反码转换问题
## 问题描述
小C在学习二进制运算,他了解到每个非负整数都有其二进制表示。例如,整数 5 可以被表示为二进制 "101",整数 11 可以被表示为二进制 "1011",并且除了 N = 0 外,任何二进制表示中都不含前导零。二进制的反码表示是将每个 1 变为 0,每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"。现在小C想知道,给定一个十进制数 N,它的二进制反码对应的十进制数是多少。## 测试样例
样例1:输入:N = 5
输出:2样例2:输入:N = 10
输出:5样例3:输入:N = 0
输出:1

问题分析:

其实这是一刀特别简单的题目,第一步将十进制转换为二进制,第二部 按位取反,第三步 取反的二进制转换为十进制

代码如下:

public class Main {public static int solution(int N) {String binaryString = Integer.toBinaryString(N);//System.out.println(binaryString);StringBuilder binaryStringBuilder = new StringBuilder(binaryString);for (int i = 0; i < binaryStringBuilder.length(); i++) {if (binaryStringBuilder.charAt(i) == '1') {binaryStringBuilder.setCharAt(i, '0');} else {binaryStringBuilder.setCharAt(i, '1');}}//System.out.println(binaryStringBuilder);int result = Integer.parseInt(binaryStringBuilder.toString(), 2);return result;}  public static void main(String[] args) {  System.out.println(solution(5) == 2 ? "Pass" : "Fail"); // 输出 Pass  System.out.println(solution(10) == 5 ? "Pass" : "Fail"); // 输出 Pass  System.out.println(solution(0) == 1 ? "Pass" : "Fail"); // 输出 Pass  }  
}

中等题目

已完成 4

简单四则运算

# 问题描述实现一个基本的计算器来计算一个简单的字符串表达式的值。注意事项如下:- 输入是一个字符串表达式(可以假设所给定的表达式都是有效的)- 字符串表达式可以包含的运算符号为:左括号 `(`, 右括号 `)`, 加号 `+`, 减号 `-`- 可以包含的数字为:非负整数(< 10)- 字符串中不包含空格- 处理除法 case 的时候,可以直接省略小数部分结果,只保留整数部分参与后续运算- 请不要使用内置的库函数 `eval`## 输入格式如:`3+4*5/(3+2)`## 数据约束见题目描述## 输出格式计算之后的数字**输入样例**:
- `1+1`
- `3+4*5/(3+2)`
- `4+2*5-2/1`
- `(1+(4+5+2)-3)+(6+8)`**输出样例**:
- `2`
- `7`
- `12`
- `23`

问题分析:

其实这是一道数据结构的题目,如果仔细学过数据结构或者考研考过,这是栈的应用,通过符号的优先级来确定入栈还是出栈,最后留在栈里的就是结果。

代码如下:

import java.util.*;
public class Main {// 返回运算符的优先级private static int precedence(char op) {if (op == '+' || op == '-') {return 1;}if (op == '*' || op == '/') {return 2;}return 0;}// 执行操作private static int applyOp(int a, int b, char op) {switch (op) {case '+': return a + b;case '-': return a - b;case '*': return a * b;case '/': return a / b; // 直接取整数部分结果}return 0;}// 计算表达式的值public static int solution(String tokens) {Stack<Integer> values = new Stack<>(); // 值栈Stack<Character> ops = new Stack<>(); // 运算符栈for (int i = 0; i < tokens.length(); i++) {// 跳过空格if (tokens.charAt(i) == ' ') {continue;}// 当前字符是数字,解析完整的数字if (Character.isDigit(tokens.charAt(i))) {int val = 0;while (i < tokens.length() && Character.isDigit(tokens.charAt(i))) {val = (val * 10) + (tokens.charAt(i) - '0');i++;}i--; // 补偿最后多加的一次递增values.push(val);} // 当前字符是左括号,直接压入运算符栈else if (tokens.charAt(i) == '(') {ops.push(tokens.charAt(i));} // 当前字符是右括号,处理栈中的运算符直到遇到左括号else if (tokens.charAt(i) == ')') {while (!ops.empty() && ops.peek() != '(') {int val2 = values.pop();int val1 = values.pop();char op = ops.pop();values.push(applyOp(val1, val2, op));}// 弹出左括号if (!ops.empty()) {ops.pop();}} // 当前字符是运算符else {while (!ops.empty() && precedence(ops.peek()) >= precedence(tokens.charAt(i))) {int val2 = values.pop();int val1 = values.pop();char op = ops.pop();values.push(applyOp(val1, val2, op));}ops.push(tokens.charAt(i));}}// 处理栈中剩余的运算符while (!ops.empty()) {int val2 = values.pop();int val1 = values.pop();char op = ops.pop();values.push(applyOp(val1, val2, op));}// 栈中应该只剩下一个值,即表达式的计算结果return values.pop();}public static void main(String[] args) {// 测试用例System.out.println(solution("1+1") == 2); // trueSystem.out.println(solution("3+4*5/(3+2)") == 7); // trueSystem.out.println(solution("4+2*5-2/1") == 12); // trueSystem.out.println(solution("(1+(4+5+2)-3)+(6+8)") == 23); // true}
}

运行结果:

数字翻译成字符串有多少种可能性

# 问题描述给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。## 输入格式一个 `int` 型的数字,`0 <= num <= 2` 的 31 次方## 输出格式也是一个 `int` 型数字,代表字符串的总共可能性**输入样例**输入: 12258**输出样例**输出: 5解释: 12258 有 5 种不同的翻译,分别是 "bccfi", "bwfi", "bczi", "mcfi" 和 "mzi"

问题分析:

要解决这个问题,即计算一个数字的不同翻译方法,实际上可以通过动态规划来实现。我们需要将输入数字看作一串字符,然后根据规则将其翻译成相应的字符串。

解决思路

动态规划:

我们定义一个动态规划数组 dp,其中 dp[i] 表示在前 i 个字符的翻译方案数量。

对于一个长度为 n 的字符串,我们考虑以下两种情况:

只将当前字符翻译成对应的字母。

将当前字符和前一个字符结合起来翻译(需要确保这两个字符组成的数字合法,且在 025 之间)。

状态转移方程:

dp[i] = dp[i - 1] 如果当前字符可以单独翻译(即非零)。

dp[i] += dp[i - 2] 如果前两个字符可以合并翻译(即它们组合成的数字在 1025 之间)。

代码如下:

public class Main {public static int solution(int num) {String str = String.valueOf(num); // 将数字转成字符串int n = str.length();if (n == 0) return 0;if (n == 1) return 1; // 单字符的情况// 动态规划数组int[] dp = new int[n + 1];dp[0] = 1; // 空字符串一种方式dp[1] = 1; // 一个字符也有一种方式for (int i = 2; i <= n; i++) {// 只翻译当前字符dp[i] = dp[i - 1];// 结合前一个字符一起翻译int twoDigit = Integer.parseInt(str.substring(i - 2, i)); // 当前字符及前一个字符形成的数if (twoDigit >= 10 && twoDigit <= 25) {dp[i] += dp[i - 2]; // 如果能够组合翻译}}return dp[n]; // 返回总的翻译方式}public static void main(String[] args) {// You can add more test cases hereSystem.out.println(solution(12258) == 5);System.out.println(solution(1400112) == 6);System.out.println(solution(2110101) == 10);}
}

运行结果:

最大异或和计算

# 最大异或和计算
## 问题描述
给定两个长度为 n 的数组 a 和 b,定义 f(c) 为数组 c 的所有元素的总和。现在,你需要恰好删除数组 a 或者数组 b 中的一个元素,使得 f(a) 和 f(b) 的异或结果最大。请输出这个最大的异或和。## 测试样例
样例1:输入:n = 3,a = [1, 2, 3],b = [3, 2, 1]
输出:5样例2:输入:n = 4,a = [4, 5, 6, 7],b = [7, 8, 9, 10]
输出:51样例3:输入:n = 5,a = [10, 20, 30, 40, 50],b = [50, 40, 30, 20, 10]
输出:248

问题分析:

第一步分别计算两个数组的总和,第二步遍历数组A,通过尝试删除每一个元素的数组A的和和数组B的和异或,然后通过迭代比较,获取最大值,第三步 类似于第二步,只不过这一步遍历的是数组B,删除B的每一个元素。

总之,通过不断比较得出最大异或和的值

代码如下:

public class Main {public static int solution(int n, int[] a, int[] b) {// 计算数组 a 和 b 的总和int sumA = 0;int sumB = 0;for (int num : a) {sumA += num;}for (int num : b) {sumB += num;}int maxXor = 0;// 尝试删除数组 a 中的每一个元素for (int i = 0; i < n; i++) {int newSumA = sumA - a[i];int newSumB = sumB;maxXor = Math.max(maxXor, newSumA ^ newSumB);}// 尝试删除数组 b 中的每一个元素for (int i = 0; i < n; i++) {int newSumA = sumA;int newSumB = sumB - b[i];maxXor = Math.max(maxXor, newSumA ^ newSumB);}return maxXor;}public static void main(String[] args) {System.out.println(solution(3, new int[]{1, 2, 3}, new int[]{3, 2, 1}) == 5);System.out.println(solution(4, new int[]{4, 5, 6, 7}, new int[]{7, 8, 9, 10}) == 51);System.out.println(solution(5, new int[]{10, 20, 30, 40, 50}, new int[]{50, 40, 30, 20, 10}) == 248);}
}

提交结果:

五子棋获胜策略

# 问题描述
- 假设存在一个五子棋棋盘,大小未知。上面只摆放了一些白色的棋子,现在你的手中还有一个白色棋子,要求找出在棋盘的哪些位置摆放这个棋子,能够使棋盘上出现五颗棋子连成一线。
- 备注:棋盘上当前不存在连成一条线的五个棋子,但至少存在一个点能够凑出五子一线(不限于横、竖、斜线)## 输入格式
- 第一行输入一个正整数 `n`,表示棋盘的宽度,棋盘总共可以容纳 `n^2` 个棋子。
- 第 2 到 `n+1` 行输入 `n` 个数字。每次输入 `n` 个数,其中 `1` 代表有棋子,`0` 代表没有棋子。## 输出格式
- 如果有 `n` 个可放置点,输出 `n` 行。
- 每行输出两个数字,以空格分隔,分别代表放置点在棋盘上的行数和列数。
- 输出顺序需要按照行数从小到大、列数从小到大的顺序。## 输入样例
```
6  
0 0 0 0 0 0  
0 1 0 0 0 0  
0 0 1 0 0 0  
0 0 0 1 0 0  
0 0 0 0 1 0  
0 0 0 0 0 0  
```## 输出样例1 1
6 6## 数据范围
- 第一行中,棋盘宽度为 `[1, 10)` 中的整数。
- 第 2 到 `n+1` 行中,只会出现 `0` 或 `1`。

问题分析:

这个题目跟我之前做过的一个题目很像,那个是动态的,双方互相落子判断谁胜利,这个是给你一个棋局,没有黑白方,判断落子胜利有几种方式,原理就是落子时,判断上下左右左斜右斜,且在规定范围内,是否可以达到五子连珠。

代码如下:

import java.util.ArrayList;
import java.util.List;
public class Main {// 检查某个位置是否可以形成五子连线public static boolean canFormLine(int x, int y, int[][] board, int n) {// 定义四个方向:右,下,右下,左下int[][] directions = {{1, 0}, {0, 1}, {1, 1}, {1, -1}};for (int[] dir : directions) {int count = 1; // 当前位置记为1int dx = dir[0], dy = dir[1];// 检查正向for (int step = 1; step < 5; ++step) {int nx = x + dx * step;int ny = y + dy * step;if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == 1) {count++;} else {break;}}// 检查反向for (int step = 1; step < 5; ++step) {int nx = x - dx * step;int ny = y - dy * step;if (nx >= 0 && nx < n && ny >= 0 && ny < n && board[nx][ny] == 1) {count++;} else {break;}}// 如果形成五子连接,则返回 trueif (count >= 5) return true;}return false; // 没有符合条件的连线}// 主解决方案函数public static int[][] solution(int n, int[][] board) {List<int[]> results = new ArrayList<>();// 检查每个位置是否能放置新棋子形成五子连线for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {if (board[i][j] == 0) { // 只检查空位if (canFormLine(i, j, board, n)) {results.add(new int[]{i + 1, j + 1}); // 记录行列,+1因要求从1开始}}}}// 将结果转换为二维数组int[][] resultArray = new int[results.size()][2];for (int i = 0; i < results.size(); i++) {resultArray[i] = results.get(i);}return resultArray.length > 0 ? resultArray : new int[][]{{-1, -1}}; // 如果没有结果,返回 {-1, -1}}public static void main(String[] args) {// 测试用例int[][] array = {{0, 0, 0, 0, 0, 0},{0, 1, 0, 0, 0, 0},{0, 0, 1, 0, 0, 0},{0, 0, 0, 1, 0, 0},{0, 0, 0, 0, 1, 0},{0, 0, 0, 0, 0, 0}};int[][] expectedOutput = {{1, 1}, {6, 6}};System.out.println(java.util.Arrays.deepEquals(solution(6, array), expectedOutput)); // 验证测试结果}
}

运行结果:

困难题目

已完成 2

二进制之和

# 问题描述给定两个二进制字符串,返回他们的和(用十进制字符串表示)。输入为非空字符串且只包含数字 1 和 0 ,请考虑大数问题。时间复杂度不要超过 O(n^2),其中 n 是二进制的最大长度。## 输入格式每个样例只有一行,两个二进制字符串以英文逗号“,”分割## 输出格式输出十进制格式的两个二进制的和**输入样例**:101,110**输出样例**:11**数据范围**:每个二进制不超过 100 个字符,JavaScript 语言下请考虑大数的情况。

问题分析:

  1. 函数签名:
    • string addBinary(const string &a, const string &b):这个函数接收两个二进制字符串,并返回它们的十进制和作为字符串。
  1. 变量初始化:
    • string result;:用于存储二进制加法的中间和最终结果(在反转之前)。
    • int carry = 0;:初始化进位为0。
    • int i = a.size() - 1;int j = b.size() - 1;:分别初始化两个字符串的索引,从末尾开始遍历。
  1. 循环逻辑:
    • while (i >= 0 || j >= 0 || carry):当任一字符串还有未处理的位或存在进位时,继续循环。
    • 在循环内部,首先处理进位,然后根据索引 ij 的有效性,将对应位置的字符转换为数字并加到 sum 上。
    • 更新进位 carry 和结果字符串 result
  1. 结果处理:
    • reverse(result.begin(), result.end());:由于是从字符串末尾开始构建结果,因此最后需要反转字符串。
    • long long decimalSum = stoll(result, 0, 2);:将二进制字符串转换为十进制长整数。这一步实际上是多余的,因为题目要求返回的是十进制字符串,而不是长整数。
    • return to_string(decimalSum);:将十进制长整数转换回字符串并返回。由于前面的 stoll 转换是多余的,这一步也可以优化为直接返回 result 字符串(在反转之后)。

代码如下:

public class Main {// 函数用于二进制字符串的加法public static String solution(String a, String b) {StringBuilder result = new StringBuilder();int carry = 0;  // 进位int i = a.length() - 1; // 指向a字符串的最后一个字符int j = b.length() - 1; // 指向b字符串的最后一个字符// 处理加法直到两个字符串都结束并且没有进位while (i >= 0 || j >= 0 || carry != 0) {int sum = carry; // 先将进位加上// 将字符转换为数字并加到sum中if (i >= 0) {sum += a.charAt(i) - '0'; i--;}if (j >= 0) {sum += b.charAt(j) - '0'; j--;}carry = sum / 2; // 计算新的进位result.append(sum % 2); // 结果取余,存入结果中}result.reverse(); // 反转结果long decimalSum = Long.parseLong(result.toString(), 2); // 转换为十进制return Long.toString(decimalSum); // 返回十进制字符串
}public static void main(String[] args) {// 测试用例System.out.println(solution("101", "110").equals("11")); // trueSystem.out.println(solution("111111", "10100").equals("83")); // trueSystem.out.println(solution("111010101001001011", "100010101001").equals("242420")); // trueSystem.out.println(solution("111010101001011", "10010101001").equals("31220")); // true
}
}

运行结果:

查找热点数据

# 问题描述给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按任意顺序返回答案。- 1 <= nums.length <= 10^5
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的你所设计算法的时间复杂度必须优于 O(n log n) ,其中 n 是数组大小。**示例 1**输入: nums = [1,1,1,2,2,3], k = 2输出: [1,2]**示例 2**输入: nums = [1], k = 1输出: [1]

问题分析:

  1. 参数:
    • vector<int>& nums: 输入的整数数组。
    • int k: 需要返回的前k个高频元素的数量。
  1. 局部变量:
    • unordered_map<int, int> freqMap: 用于存储每个数字的频率。
    • vector<pair<int,int>> result: 存储哈希表中的键值对(数字及其频率)。
    • stringstream ss: 用于构建最终返回的字符串。
  1. 逻辑流程:
    • 构建频率映射: 遍历输入数组 nums,使用 unordered_map 记录每个数字的频率。
    • 存储映射到结果向量: 将 freqMap 中的每个键值对(数字及其频率)添加到 result 向量中。
    • 排序: 使用 sort 函数对 result 向量进行排序,排序依据是元素的频率(降序)。
    • 构建返回字符串: 遍历排序后的 result 向量的前 k 个元素,将它们转换为字符串并使用逗号分隔,存储在 stringstream 中。
    • 返回结果: 将 stringstream 中的内容转换为字符串并返回。

代码如下:

import java.util.*;
public class Main {public static String solution(int[] nums, int k) {// 使用哈希表记录每个元素的频率Map<Integer, Integer> freqMap = new HashMap<>();for (int num : nums) {freqMap.put(num, freqMap.getOrDefault(num, 0) + 1);}// 将频率存储到列表中并按频率排序List<Map.Entry<Integer, Integer>> resultList = new ArrayList<>(freqMap.entrySet());resultList.sort((a, b) -> b.getValue().compareTo(a.getValue())); // 按频率降序排序// 创建结果字符串StringBuilder sb = new StringBuilder();for (int i = 0; i < k; i++) {sb.append(resultList.get(i).getKey());if (i < k - 1) {sb.append(","); // 添加逗号分隔}}return sb.toString(); // 返回结果字符串}public static void main(String[] args) {// 测试用例int[] nums1 = {1, 1, 1, 2, 2, 3};int[] nums2 = {1};// 输出结果是否与预期相符System.out.println(solution(nums1, 2).equals("1,2")); // trueSystem.out.println(solution(nums2, 1).equals("1")); // true}
}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/455139.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图解版】力扣第146题:LRU缓存

力扣第146题&#xff1a;LRU缓存 一、LRU算法1. 基本概念2. LRU 和 LFU 的区别&#xff1a;3. 为什么 LRU 不需要记录使用频率&#xff1f; 二、Golang代码实现三、代码图解1. LRUCache、DLinkedNode两个结构体2. 初始化结构体对象3. addToHead函数4. removeNode函数5. moveToH…

rust grpc demo

文章目录 1. 创建项目2. 配置proto2.1 配置Cargo.toml, 内容如下&#xff1a;2.2 创建文件proto/hello.proto, 内容如下&#xff1a;2.3 添加build.rs文件&#xff0c; 内容如下&#xff1a;2.4 项目结构如下&#xff1a;2.5 编译proto文件 3.0 处理服务3.1 项目引入3.2 添加sr…

多模态大语言模型(MLLM)-Deepseek Janus

论文链接&#xff1a;https://arxiv.org/abs/2410.13848 代码链接&#xff1a;https://github.com/deepseek-ai/Janus 本次解读Janus: Decoupling Visual Encoding for Unified Multimodal Understanding and Generation 前言 Deepseek出品&#xff0c;必属精品。 创新点 传…

docker容器无法连接宿主机mysql排查

1、docker无法访问宿主机 在docker容器内&#xff0c;需要访问当前docker容器的网关&#xff0c;例如172.xx.0.1&#xff0c;即可访问宿主机&#xff0c;因此需要保证docker的网络配置正确 查看当前docker容器的网关&#xff1a; docker inspect 你的容器名或者容器id 显示…

【纯前端excel导出】vue2纯前端导出excel,使用xlsx插件,修改样式、合并单元格

官网&#xff1a; 1、xlsx-js-style xlsx-js-style | xlsx-js-style homepage 2、xlsx SheetJS 中文网 一、使用第三方插件 1、安装 npm install xlsx-js-style 2、引入 import xlsx from xlsx-js-style xlsx插件是基础的导出&#xff0c;不可以修改样式&#xff0c;直接xlsx-s…

文通车牌识别相机在工地称重应用中的卓越表现

在现代工地管理中&#xff0c;高效、准确的称重系统是确保工程顺利进行的关键之一。而文通车牌识别相机的出现&#xff0c;为工地称重应用带来了全新的解决方案。 一、工地称重面临的挑战 传统的工地称重方式往往存在着一些问题。人工记录车牌和重量信息容易出现错误&#xff0…

python-----函数详解(一)

一、概念及作用&#xff1a; 概念&#xff1a;由若干条语句组成语句块&#xff0c;其中包括函数名称、参数列表&#xff0c;它是组织代码的最小单元&#xff0c;完成一定的功能 作用&#xff1a;把一个代码封装成一个函数&#xff0c;一般按功能组织一段代码 目的就是为了重…

基于单片机的智能小区门禁系统设计(论文+源码)

1总体架构 智能小区门禁系统以STM32单片机和WiFi技术为核心&#xff0c;STM32单片机作为主控单元&#xff0c;通过WiFi模块实现与手机APP的连接&#xff0c;构建整个门禁系统。系统硬件包括RFID模块、指纹识别模块、显示屏、按键以及继电器。通过RFID绑定IC卡、APP面部识别、指…

百度搜索推广和信息流推广的区别,分别适用于什么场景!

信息流推广和搜索广告&#xff0c;不仅仅是百度&#xff0c;是很多平台的两个核心推广方式。 1、搜索广告&#xff1a; 就是基于用户的搜索习惯&#xff0c;更多是用户有疑问、还有用户当下就要做出行动的广告。 比如上门服务、线上咨询服务、招商加盟、了解产品各种型号和信…

STM32G4系列MCU的低功耗模式介绍

目录 概述 1 认识低功耗模式 1.1 低功耗模式的应用 1.2 低功耗模式介绍 2 低功耗模式的状态关系 2.1 低功耗模式可能的转换状态图 2.2 低功耗模式总结 3 运行模式 3.1 减慢系统时钟 3.2 外围时钟门控 3.3 低功耗运行模式&#xff08;LP运行&#xff09; 概述 本文主…

react 基础学习笔记

1.react 语法 ①数据渲染 函数组件将HTML结构直接写在函数的返回值中 JSX只能有一个根元素 JSX插值写法 插值可以使用的位置 1.标签内容&#xff1b; 2.标签属性 JSX 条件渲染&#xff1a;三目运算符&#xff1b; JSX根据数据进行列表渲染&#xff1a;map()方法&#x…

QT 机器视觉 1.相机类型

本专栏从实际需求场景出发详细还原、分别介绍大型工业化场景、专业实验室场景、自动化生产线场景、各种视觉检测物体场景介绍本专栏应用场景 更适合涉及到视觉相关工作者、包括但不限于一线操作人员、现场实施人员、项目相关维护人员&#xff0c;希望了解2D、3D相机视觉相关操作…

微服务与多租户详解:架构设计与实现

引言 在现代软件开发领域&#xff0c;微服务架构和多租户架构是两个重要的概念。微服务架构通过将应用程序拆分为多个独立的服务&#xff0c;提升了系统的灵活性和可维护性。而多租户架构则通过共享资源来服务多个客户&#xff0c;提高了资源利用率和系统的经济性。 一、微服务…

OpenCV的常用与形状形状描述相关函数及用法示例

OpenCV提供了提供了多种用于形状描述和分析的函数。这些函数能够帮助你提取图像中的形状特征&#xff0c;进行形状匹配、识别和分析。下面介绍一些常用的形状描述函数&#xff1a; 轮廓检测函数findContours() findContours()函数用于在二值图像中查找轮廓。有两个原型函数&…

【zlm】 webrtc源码讲解(二)

目录 webrtc播放 MultiMediaSourceMuxer里的_ring webrtc播放 > MediaServer.exe!mediakit::WebRtcPlayer::onStartWebRTC() 行 60 CMediaServer.exe!mediakit::WebRtcTransport::OnDtlsTransportConnected(const RTC::DtlsTransport * dtlsTransport, RTC::SrtpSession::…

tomcat部署war包部署运行,IDEA一键运行启动tomacat服务,maven打包为war包并部署到tomecat

tomcat部署war包前端访问 在Java Web开发中&#xff0c;Tomcat是一个非常流行的开源Web服务器和Servlet容器。它实现了Java Servlet和JavaServer Pages (JSP) 技术&#xff0c;提供了一个纯Java的Web应用环境。本文将介绍如何在Tomcat中部署运行WAR包&#xff0c;让你的应用快…

vue2 使用环境变量

一. 在根目录下创建.env.xxx文件 .env 基础系统变量&#xff0c;无论何种环境&#xff0c;都可使用其中配置的值&#xff0c;其他环境中的变量会覆盖.env中的同名变量。 .env.development 开发环境 .env.production 生产环境 .env.staging 测试环境 二. 内容格式 vue2 使用是以…

GRU神经网络理解

全文参考以下B站视频及《神经网络与深度学习》邱锡鹏&#xff0c;侧重对GPU模型的理解&#xff0c;初学者入门自用记录&#xff0c;有问题请指正【重温经典】GRU循环神经网络 —— LSTM的轻量级版本&#xff0c;大白话讲解_哔哩哔哩_bilibili 更新门、重置门、学习与输出 注&a…

STM32(二十一):看门狗

WDG&#xff08;Watchdog&#xff09;看门狗&#xff0c;手动重装寄存器的操作就是喂狗。 看门狗可以监控程序的运行状态&#xff0c;当程序因为设计漏洞、硬件故障、电磁干扰等原因&#xff0c;出现卡死或跑飞现象时&#xff0c;看门狗能及时复位程序&#xff0c;避免程序陷入…

数学建模微分方程模型——传染病模型

病毒也疯狂&#xff1a;细说传染病微分方程模型的那些事儿 “数学是打开科学大门的钥匙&#xff0c;而微分方程则是理解世界变化的密码。” 大家好&#xff01;今天我们要聊一聊一个既严肃又有趣的话题——传染病微分方程模型。别急&#xff0c;听起来高大上&#xff0c;其实一…