青训营题目小k的找不同挑战+给定字符串的字符去重问题题解

4 阅读4分钟

小k的找不同挑战

1.问题描述

小R需要找出给定数组中只出现一次的最小数字。如果所有数字都出现多次,则返回-1。

2.解题思路

2.1问题分析

  • 输入:一个整数 n 表示数组的长度,一个整数数组 nums
  • 输出:只出现一次的最小数字,如果没有这样的数字则返回-1。

2.2基本思路

  1. 统计频率:使用 Counter 统计每个数字的出现频率。
  2. 筛选唯一数字:从 Counter 中筛选出只出现一次的数字。
  3. 找出最小值:如果存在只出现一次的数字,找出其中的最小值;否则返回-1。

2.3数据结构选择

  • 使用 Counter 来统计每个数字的出现频率。
  • 使用列表来存储只出现一次的数字,便于后续查找最小值。

2.4代码

from collections import Counter
def solution(n: int, nums: list) -> int:
    # write code here
    d=Counter(nums)
    res=[a for a in d.keys() if d[a]==1]
    if not res:
        return -1
    return min(res)


if __name__ == '__main__':
    print(solution(n = 3, nums = [6, 6, 6]) == -1)
    print(solution(n = 3, nums = [6, 9, 6]) == 9)
    print(solution(n = 5, nums = [1, 2, 2, 3, 3]) == 1)

3.代码详解

统计频率

freq = Counter(nums)

使用 Counter 统计 nums 中每个数字的出现频率。

筛选唯一数字

unique_nums = [num for num in freq if freq[num] == 1]

通过列表推导式筛选出只出现一次的数字。

返回结果

if not unique_nums:
    return -1
return min(unique_nums)

如果 unique_nums 为空,说明没有只出现一次的数字,返回-1;否则返回 unique_nums 中的最小值。

给定字符串的字符去重问题

1.问题描述

给定一个字符串 ss,你需要通过删除一些字符,使得每个字符在字符串中出现的次数均不相同。你需要找出最少需要删除的字符数量以达到这个目标。

2.解题思路

2.1问题分析

  • 首先,我们需要统计字符串中每个字符的出现次数。
  • 然后,我们需要确保这些出现次数都是唯一的。
  • 如果某些字符的出现次数相同,我们需要通过删除字符来调整这些次数,使得它们变得不同。
  • 目标是找到最少的删除次数。

2.2基本思路

  1. 统计频率:使用 Counter 统计每个字符的出现次数。
  2. 排序频率:将这些频率按从大到小排序。
  3. 调整频率:从第二个频率开始,如果当前频率大于或等于前一个频率,则减少当前频率直到它小于前一个频率。每次减少频率时,记录删除次数。
  4. 返回结果:返回记录的删除次数。

2.3示例

  • 对于字符串 "aab",字符 "a" 出现2次,字符 "b" 出现1次,这些出现次数已经不同,因此不需要删除任何字符,输出为0。
  • 对于字符串 "aaabbbcc",字符 "a" 和 "b" 各出现3次,字符 "c" 出现2次。我们需要将 "a" 和 "b" 的出现次数调整为2和1,总共删除2次,输出为2。

2.4代码

from collections import Counter

def solution(s: str) -> int:
    # 统计字符频率
    freq = Counter(s)
    
    # 将频率排序
    freq_values = sorted(freq.values(), reverse=True)
    
    delete_count = 0
    
    # 遍历频率列表,调整频率
    for i in range(1, len(freq_values)):
        while freq_values[i] >= freq_values[i-1] and freq_values[i] > 0:
            # 减少当前频率直到它与其他频率不同
            freq_values[i] -= 1
            delete_count += 1
    
    return delete_count

if __name__ == '__main__':
    print(solution("aab") == 0)
    print(solution("aaabbbcc") == 2)
    print(solution("abcdef") == 5)

3.代码详解

  1. 统计频率

freq = Counter(s)

使用 `Counter` 统计字符串中每个字符的出现次数。
  1. 排序频率freq_values = sorted(freq.values(), reverse=True)

    将这些频率按从大到小排序,以便后续调整。

  2. 调整频率

 for i in range(1len(freq_values)):

        while freq_values[i] >= freq_values[i-1] 

        and freq_values[i] > 0:

            freq_values[i] -= 1

            delete_count += 1
从第二个频率开始,如果当前频率大于或等于前一个频率,则减少当前频率直到它小于前一个频率。每次减少频率时,记录删除次数。
  1. 返回结果

通过这种方式,我们可以确保每个字符的出现次数都是唯一的,并且删除的字符数量最少。

至此,完结撒花!