第一题 找单独的数
问题描述
在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求:
- 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
- 尽量减少额外空间的使用,以体现你的算法优化能力。
测试样例
样例1:
输入:
cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
输出:4
解释:拿到数字 4 的同学是唯一一个没有配对的。
样例2:
输入:
cards = [0, 1, 0, 1, 2]
输出:2
解释:数字 2 只出现一次,是独特的卡片。
样例3:
输入:
cards = [7, 3, 3, 7, 10]
输出:10
解释:10 是班级中唯一一个不重复的数字卡片。
约束条件
- 1 ≤ cards.length ≤ 1001
- 0 ≤ cards[i] ≤ 1000
- 班级人数为奇数
- 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次
问题思考
这道题目要求我们找出一个数组中唯一一个只出现一次的数字。数组中的其他数字都恰好出现了两次。这是一个典型的查找问题,可以通过哈希表或者位运算来解决。考虑到题目要求时间复杂度为 O(n) 并且尽量减少额外空间的使用,我们可以使用位运算的方法来解决这个问题。
解题思路
- 理解问题:我们需要找出数组中唯一一个出现次数为奇数次的数字。
- 使用异或运算:异或运算具有以下性质:a ^ a = 0(任何数与自身异或结果为0),a ^ 0 = a(任何数与0异或结果为它本身),以及 a ^ b ^ a = b(异或运算满足交换律和结合律)。由于数组中除了一个数字外,其他数字都出现了两次,我们可以利用异或运算来找出那个只出现一次的数字。
- 遍历数组:遍历数组中的每个数字,将它们依次进行异或运算。由于相同数字异或结果为0,最后剩下的结果就是那个只出现一次的数字。
算法实现
int findSingle(int* cards, int cardsSize) {
int result = 0;
for (int i = 0; i < cardsSize; i++) {
result ^= cards[i];
}
return result;
}
时间复杂度分析
- 时间复杂度:O(n),其中 n 是数组的长度。我们只需要遍历一次数组,对每个元素进行一次异或运算。
- 空间复杂度:O(1),我们只需要一个额外的变量来存储异或的结果,不需要额外的空间。
解题代码(python)
def solution(cards):
# Edit your code here
unique_number=0;
for card in cards:
unique_number^=card
return unique_number
if __name__ == "__main__":
# Add your test cases here
print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4)
print(solution([0, 1, 0, 1, 2]) == 2)
第三题 数字字符串结构化
问题描述
小M在工作时遇到了一个问题,他需要将用户输入的不带千分位逗号的数字字符串转换为带千分位逗号的格式,并且保留小数部分。小M还发现,有时候输入的数字字符串前面会有无用的 0,这些也需要精简掉。请你帮助小M编写程序,完成这个任务。
测试样例
样例1:
输入:
s = "1294512.12412"
输出:'1,294,512.12412'
样例2:
输入:
s = "0000123456789.99"
输出:'123,456,789.99'
样例3:
输入:
s = "987654321"
输出:'987,654,321'
问题思考
这道题目要求编写一个程序,将一个数字字符串转换成一个特定格式的字符串,具体要求如下:
-
添加千分位逗号:将输入的数字字符串转换为带有千分位逗号的格式。这意味着每三位数字需要用逗号分隔。例如,数字
1294512应该转换为1,294,512。 -
保留小数部分:如果输入的数字字符串包含小数点,则需要保留小数点及其后面的数字。例如,
1294512.12412转换后应为1,294,512.12412。 -
精简无用的0:输入的数字字符串可能以零开头,这些前导零需要被去掉。例如,
0000123456789.99应该转换为123,456,789.99。 -
处理整数:如果输入的数字字符串是一个整数(没有小数点),则直接在每三位数字间添加逗号。例如,
987654321转换后应为987,654,321。
解题思路
-
识别小数点:首先,需要确定字符串中是否有小数点,并记住小数点的位置。
-
去除前导零:遍历字符串,去除前导零。如果整个字符串都是零,则结果应为
"0"。 -
分组:从小数点开始,分别处理整数部分和小数部分。对于整数部分,从右向左每三位数字添加一个逗号。
-
拼接:将处理后的整数部分和小数部分拼接起来,形成最终的字符串。
解题代码(python)
def solution(s: str) -> str:
# write code here
integer_part, *decimal_part = s.split('.')
integer_part = integer_part.lstrip('0')
if integer_part == '':
integer_part = '0'
decimal_part = decimal_part[0] if decimal_part else ''
formatted_integer_part = '{:,}'.format(int(integer_part))
# 只有在有小数部分的情况下才添加小数点
if decimal_part:
result = formatted_integer_part + '.' + decimal_part
else:
result = formatted_integer_part
return result
if __name__ == '__main__':
print(solution("1294512.12412") == '1,294,512.12412')
print(solution("0000123456789.99") == '123,456,789.99')
print(solution("987654321") == '987,654,321')
第四题 数字分组求偶数和
问题描述
小M面对一组从 1 到 9 的数字,这些数字被分成多个小组,并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。
numbers: 一个由多个整数字符串组成的列表,每个字符串可以视为一个数字组。小M需要从每个数字组中选择一个数字。
例如对于[123, 456, 789],14个符合条件的数为:147 149 158 167 169 248 257 259 268 347 349 358 367 369。
测试样例
样例1:
输入:
numbers = [123, 456, 789]
输出:14
样例2:
输入:
numbers = [123456789]
输出:4
样例3:
输入:
numbers = [14329, 7568]
输出:10
问题思考
这道题目是一个组合问题,目标是找出所有可能的数字组合,使得这些数字的各位数之和为偶数。下面是对题目的详细解析:
问题描述
- 输入:一个列表
numbers,其中每个元素是一个字符串,代表一个数字组。每个数字组由从1到9的数字组成。 - 任务:从每个数字组中选择一个数字,组成一个新的数。
- 目标:确保新数的各位数字之和为偶数。
- 输出:满足条件的不同分组和选择方法的数量。
解题思路
- 理解数字之和的奇偶性:一个数的各位数字之和为偶数,当且仅当其中奇数个数的数量为偶数(包括0个)。
- 遍历每个数字组:对于每个数字组,需要确定其中奇数和偶数的数量。
- 组合选择:对于每个数字组,有两种选择:
- 选择奇数(如果该组中有奇数)。
- 选择偶数(如果该组中有偶数)。
- 计算总组合数:对于每个数字组,计算选择奇数和偶数的组合数,然后将这些组合数相乘,得到总的组合数。
- 确保总和为偶数:需要确保所有选择的数字之和为偶数。这可以通过以下两种情况实现:
- 所有选择的数字都是偶数。
- 选择的数字中奇数的数量为偶数。
解题代码(python)
def solution(numbers):
even_ways = 1
odd_ways = 0
for number in numbers:
even_count = 0
odd_count = 0
group = str(number)
for digit in group:
num = int(digit) # 将字符转换为数字
if num % 2 == 0:
even_count += 1
else:
odd_count += 1
new_even_ways = even_ways * even_count + odd_ways * odd_count
new_odd_ways = odd_ways * even_count + even_ways * odd_count
even_ways = new_even_ways
odd_ways = new_odd_ways
return even_ways
if __name__ == "__main__":
print(solution([123, 456, 789]) == 14) # 输出: True
print(solution([123456789]) == 4) # 输出: True
print(solution([14329, 7568]) == 10) # 输出: True