文章目录

  • @[toc]
    • 第 41 题:数据流中的中位数
    • 第 42 题:连续子数组的最大和
    • 第 44 题:数字序列中某一位的数字
    • 同 LeetCode 第 400 题:[400. 第 N 个数字](https://leetcode-cn.com/problems/nth-digit/)
    • 第 45 题:把数组排成最小的数
    • 第 46 题:把数字翻译成字符串
    • LeetCode 第 91 题:解码方法
    • 第 47 题:礼物的最大价值
    • 第 48 题:最长不重复字符串的子字符串
    • 第 49 题:丑数
    • 第 50-1 题:字符串中第一个只出现一次的字符
    • 第 50-2 题:字符流中第一个不重复的字符

第 41 题:数据流中的中位数

传送门:AcWing:数据流中的中位数。

如何得到一个数据流中的中位数?

如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。

如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

样例

输入:1, 2, 3, 4输出:1,1.5,2,2.5解释:每当数据流读入一个数据,就进行一次判断并输出当前的中位数。

参考资料:LeetCode 第 295 题:数据流的中位数。

问题:1、上面的思路是很简单的,想想用 Python 如何实现。

2、LeetCode 上面第 4 题:排序数组的中位数如何求?

另一种使用堆的解法:这道题是堆解决的问题。

用两个堆:max heap 和 min heap,再一个median值, 维持两个堆的大小相等(max堆可以比min堆多一个). 对于新来的元素,比较新元素和median的大小,如果大于median就放入最小堆里面,如果小于median就放入最大堆里面,如果max heap,和min heap不平衡了,就调整一下。 然后调整过后median 里面的值就是我们要求的中位数。

C++ 代码:

第 42 题:连续子数组的最大和

传送门:连续子数组的最大和。

输入一个 非空 整型数组,数组里的数可能为正,也可能为负。

数组中一个或连续的多个整数组成一个子数组。

求所有子数组的和的最大值。

要求时间复杂度为 O(n)O(n)O(n)。

样例:

输入:[1, -2, 3, 10, -4, 7, 2, -5]

输出:18

同 LeetCode 第 53 题,题解传送门:LeetCode 第 53 题:连续子数组的最大和。

“大雪菜”的做法:状态:以前一个数结尾的“连续子数组的最大和”为状态。

C++ 代码:

###第 43 题:整数中 1 出现的次数(从 1 到 n 整数中 1 出现的次数)

传送门:AcWing:从 1 到 n 整数中 1 出现的次数。

输入一个整数 nnn,求从 111 到 nnn 这 nnn 个整数的十进制表示中 111 出现的次数。

例如输入 121212,从 111 到 121212 这些整数中包含 111 的数字有 111,101010,111111 和 121212,“111” 一共出现了 555 次。

样例:

输入: 12
输出: 5

同 LeetCode 第 233 题:数字 111 的个数。

大雪菜的解法:

C++ 代码:

思路:

Python 代码:

# 56. 从1到n整数中1出现的次数
#
# 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
#
# 例如输入12,从1到12这些整数中包含“1”的数字有1,10,11和12,其中“1”一共出现了5次。
#
# 样例
# 输入: 12
# 输出: 5
class Solution(object):def numberOf1Between1AndN_Solution(self, n):""":type n: int:rtype: int"""if n <= 0:return 0number = []while n:number.append(n % 10)n //= 10res = 0for i in range(len(number) - 1, -1, -1):left = 0right = 0# 想清楚这里 t 为什么从 1 开始t = 1for j in range(len(number) - 1, i, -1):left = left * 10 + number[j]for j in range(i - 1, -1, -1):right = right * 10 + number[j]t *= 10# print(left, right)# 至少有左边的数这么多res += left * t# print(number[i], left, right, t, left * t)if number[i] == 1:res += right + 1elif number[i] > 1:res += treturn resif __name__ == '__main__':solution = Solution()n = 45032result = solution.numberOf1Between1AndN_Solution(n)print('result', result)

解法1:从 111 到 nnn 遍历,每个数通过对 101010 求余数判断整数的个位数字是不是 111,大于 101010 的除以 101010 之后再判断。我们对每个数字都要做除法和求余运算以求出该数字中 111 出现的次数。如果输入数字 nnn,nnn 有 O(log⁡n)O(\log n)O(logn) 位,我们需要判断每一位是不是 111,那么时间复杂度为 O(n∗log⁡n)O(n* \log n)O(n∗logn)。这样做,计算量大,效率不高。

本文采用《数学之美》上面提出的方法,设定整数点(如 111、101010、100100100等等)作为位置点iii(对应 nnn的个位、十位、百位等等),分别对每个数位上有多少包含 111 的点进行分析。

根据设定的整数位置,对 nnn 进行分割,分为两部分,高位 n/in/in/i,低位 n%in \% in%i;

1、当 iii 表示百位,且百位对应的数 ≥2\ge2≥2,

例如 n=31456n=31456n=31456,此时考虑 i=100i=100i=100,则 a=314a=314a=314,b=56b=56b=56。

此时百位为 111 的次数有 a/10+1=32a/10+1=32a/10+1=32 批次,具体如下:

说明:第 1 批次:00100−0019900100-0019900100−00199,一共 100100100 个数;

第 2 批次:01100−0119901100-0119901100−01199,一共 100100100 个数;

……

第 32 批次:31100−3119931100-3119931100−31199,一共 100100100 个数;

最高两位 0−310-310−31,每一批次都包含 100100100 个连续的点,即共有 (a/10+1)×100(a/10+1)\times100(a/10+1)×100 个点的百位为 111;

2、当 iii 表示百位,且百位对应的数为 111,

例如 n=31156n=31156n=31156,i=100i=100i=100,则 a=311a=311a=311,b=56b=56b=56,此时百位对应的就是 111。

第 1 批次:00100−0019900100-0019900100−00199,一共 100100100 个数;

第 2 批次:01100−0119901100-0119901100−01199,一共 100100100 个数;

……

第 31 批次:30100−3019930100-3019930100−30199,一共 100100100 个数;

第 32 批次:31100−31156931100-31156931100−311569,一共 575757 个数;

则共有 a/10a/10a/10 次是包含 100100100 个连续点,最高两位 0−300-300−30。

当最高两位为 313131(即 a=311a=311a=311),本次只对应局部点 00−5600-5600−56,共 b+1b+1b+1次,所有点加起来共有 (a/10×100)+(b+1)(a/10\times100)+(b+1)(a/10×100)+(b+1),这些点百位对应为 111;

3、当 iii 表示百位,且百位对应的数为 000,如 n=31056n=31056n=31056,i=100i=100i=100,则 a=310a=310a=310,b=56b=56b=56。

第 1 批次:00100−0019900100-0019900100−00199,一共 100100100 个数;

第 2 批次:01100−0119901100-0119901100−01199,一共 100100100 个数;

……

第 31 批次:30100−3019930100-3019930100−30199,一共 100100100 个数;

第 32 批次:31000−3105631000-3105631000−31056,一共 000 个数;

此时百位为 111 的次数有 a/10=31a/10=31a/10=31,最高两位 0−300-300−30;

综合以上 333 种情况,当百位对应 000 或 ≥2\ge2≥2 时,有 (a+8)/10(a+8)/10(a+8)/10 次包含所有 100100100 个点,还有当百位为 111 (a%10==1a\%10==1a%10==1),需要增加局部点 b+1b+1b+1。

之所以补 888,是因为当百位为 000,则 a/10==(a+8)/10a/10==(a+8)/10a/10==(a+8)/10,当百位 ≥2\ge2≥2,补 888 会产生进位,效果等同于 (a/10+1)(a/10+1)(a/10+1)。

Python 代码:

class Solution:def NumberOf1Between1AndN_Solution(self, n):# write code herecount = 0i = 1while i <= n:a = n / ib = n % icount += (a+8) / 10 * i + (a % 10 == 1)*(b + 1)i *= 10return count

参考资料:https://blog.csdn.net/qq_38211852/article/details/80863364

https://cuijiahua.com/blog/2017/12/basis_31.html

第 44 题:数字序列中某一位的数字

传送门:数字序列中某一位的数字。

数字以 0123456789101112131415… 的格式序列化到一个字符序列中。

在这个序列中,第 5 位(从 0 开始计数)是 5 ,第 13 位是 1 ,第 19 位是 4 ,等等。

请写一个函数求任意位对应的数字。

样例:

输入:13

输出:1

Python 代码:参考了 LeetCode 第 400 题讨论区代码

class Solution(object):def digitAtIndex(self, n):""":type n: int:rtype: int"""# 如果 n 小于 10 ,直接返回就可以了if n < 10:return n# 计算前缀部分base = 9digits = 1# 2 位数,从 10 到 99 一共 ( 99 - 10 + 1) * 2 = 90 * 2 = 180 位# 3 位数,从 100 到 999 一共 ( 999 - 100 + 1) * 2 = 900 * 3 = 2700 位# 4 位数,从 1000 到 9999 一共 ( 9999 - 1000 + 1) * 2 = 9000 * 4 = 3600 位while n - base * digits > 0:n -= base * digitsbase *= 10digits += 1index = n % digitsif index == 0:# 计算出 num 是多少# 例如:192,有 1 个位移的偏差num = 10 ** (digits - 1) + n // digits - 1# 返回个位就可以了return num % 10else:# 不能整除,那个偏移就不用算了# 例如 194 = 189 + 5# 100 + 2 = 102num = 10 ** (digits - 1) + n // digits# 从左边向右边数,第 2 位for i in range(index, digits):num //= 10return num % 10

参考资料:

1、https://www.acwing.com/activity/content/code/content/20758/

2、https://blog.csdn.net/Koala_Tree/article/details/79536284

思路:跳过不同位数的数字,在相应位数中寻找。

以序列中第 100110011001 位为例:

1、序列前 101010 位为 000 到 999,跳过,再从后面找 991991991 位;

2、后面 180180180 位为 101010 到 999999,因为一共 99−10+1=9099-10+1=9099−10+1=90 个数,每个数 222 位,所以 180180180 位; 跳过,再从后面找 811811811 位(1001−10−180=8111001-10-180=8111001−10−180=811);

后面 270027002700 位为 100100100 到 999999999,因为 811&lt;2700811&lt;2700811<2700,所以 811811811 位是某个三位数中的一位;
由于811=270*3+1,这就是说811位是从100开始的第270个数字即370的中间一位,即7。(注意,这里都是从第0位开始计数的)


作者:Koala_Tree
来源:CSDN
原文:https://blog.csdn.net/Koala_Tree/article/details/79536284
版权声明:本文为博主原创文章,转载请附上博文链接!

Java 代码:

class Solution {  // 9*1  9*10*2  9*10*10*3public int digitAtIndex(int n) {int len = 1;long count = 9;int start = 1;while (n > len * count) {  //13  n=n-9=4 len=2 count=90 start=10 n -= len * count;      //start=10+3/2=11   答案是11的第二个1len += 1;count *= 10;start *= 10;}// start 记录当前循环区间的第一个数字,当 n 落到某一个确定的区间里了,// 那么 (n-1)/len 就是目标数字在该区间里的坐标,加上 start 就是得到了目标数字start += (n - 1) / len;String s = Integer.toString(start);return Character.getNumericValue(s.charAt((n - 1) % len));}
}

参考资料:这篇简书上的文章有详细步骤。https://www.jianshu.com/p/0bbf1fcbe070。

同 LeetCode 第 400 题:400. 第 N 个数字

说明:只不过 LeetCode 第 400 题从 1 开始,传送门:400. 第 N 个数字。

在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …中找到第 n 个数字。

注意:
n 是正数且在32为整形范围内 ( n < 231)。

示例 1:

输入:
3输出:
3

示例 2:

输入:
11输出:
0说明:
第11个数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是0,它是10的一部分。

Python 代码:

class Solution:def findNthDigit(self, n):""":type n: int:rtype: int"""# 特判:如果 n 小于 10 ,直接返回就可以了if n < 10:return n# 表示几位数# 2 位数,从 10 到 99 一共 ( 99 - 10 + 1) * 2 = 90 * 2 = 180 位# 3 位数,从 100 到 999 一共 ( 999 - 100 + 1) * 2 = 900 * 3 = 2700 位# 4 位数,从 1000 到 9999 一共 ( 9999 - 1000 + 1) * 2 = 9000 * 4 = 3600 位# 步骤1:calculate how many digits the number has# 计算前缀部分length = 0base = 9digits = 1# n = 1001 时,9 过,180 过,剩下 812# 不越界才加,要清楚这一点while length + base * digits < n:length += base * digitsbase *= 10digits += 1n -= length# step 2. calculate what the number is# 到这里,num 是 "digits 位数" 中的某一个数字# 以 digits = 3 为例,n 是 100 - 999 中的一位,num 表示是哪个数字index = n % digitsif index == 0:# 如果整除,就是那个数字的最后一位num = 10 ** (digits - 1) + n // digits - 1return num % 10else:num = 10 ** (digits - 1) + n // digitsfor i in range(index, digits):num //= 10return num % 10if __name__ == '__main__':solution = Solution()n = 190result1 = solution.findNthDigit(n)print(result1)

第 45 题:把数组排成最小的数

传送门:把数组排成最小的数。

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

例如输入数组 [3, 32, 321],则打印出这 3 个数字能排成的最小数字 321323

样例:

输入:[3, 32, 321]

输出:321323

注意:输出数字的格式为字符串。

同 LeetCode 第 179 题,最大数。

Java 代码:

public String PrintMinNumber(int[] numbers) {int len = numbers.length;if (len == 0) {return "";}String[] numsStr = new String[len];for (int i = 0; i < len; i++) {numsStr[i] = numbers[i] + "";}Arrays.sort(numsStr, (a, b) -> (a + b).compareTo(b + a));StringBuilder builder = new StringBuilder();for (int i = 0; i < len; i++) {builder.append(numsStr[i]);}return builder.toString();
}

说明:其实就定义自定义排序规则。Python3 想用 cmp 而不是 key 的话,需要 from functools import cmp_to_key ,然后 sort 或者 sorted 的时候 key = cmp_to_key(your_comparator)

Python 代码:

class Solution(object):def printMinNumber(self, nums):""":type nums: List[int]:rtype: str"""if len(nums) == 0:return ''# 自定义排序规则from functools import cmp_to_keykey_func = cmp_to_key(lambda a, b: int(a + b) - int(b + a))result = sorted(map(str, nums), key=key_func)return ''.join(result)if __name__ == '__main__':list1 = [7, -8, 5, 4, 0, -2, -5]# 要求:1、正数在前负数在后# 2、正数从小到大# 3、负数从大到小result = sorted(list1, key=lambda x: (x < 0, abs(x)))print(result)s = 'asdf234GDSdsf23'  # 排序:小写-大写-奇数-偶数print("".join(sorted(s,key=lambda x: (x.isdigit(),x.isdigit() and int(x) %2 == 0,x.isupper(),x))))

另一种写法:

Python 代码:

class NumCompare(str):# 注意:这里继承 str 类def __lt__(self, other):return self + other < other + selfclass Solution(object):def printMinNumber(self, nums):""":type nums: List[int]:rtype: str"""if len(nums) == 0:return ''# 自定义排序规则result = sorted(map(str, nums), key=NumCompare)return ''.join(result)

第 46 题:把数字翻译成字符串

传送门:把数字翻译成字符串。

给定一个数字,我们按照如下规则把它翻译为字符串:

0 翻译成 “a”,1 翻译成 “b”,……,11 翻译成“l”,……,25 翻译成 “z”。

一个数字可能有多个翻译。例如 12258 有 5 种不同的翻译,它们分别是 “bccfi”、“bwfi”、“bczi”、“mcfi” 和 “mzi”。

请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。

样例:

输入:“12258”

输出:5

思路:同 LeetCode 第 91 题 Decode Ways。使用动态规划。状态:dp[i] 表示 s[0,i] (包括 i ),一共有多少种翻译的方法。分类讨论:1、当前字符可以单独翻译;2、当前字符可以和前面一个字符一起翻译。dp[i] 就是以上二者之和。

Python 代码:

class Solution:def getTranslationCount(self, s):""":type s: str:rtype: int"""s = str(s)l = len(s)if l == 0:return 0dp = [None for _ in range(l)]# dp[i] 表示 s[0,i] ,包括 i ,一共有多少种翻译的方法dp[0] = 1for i in range(1, l):# 当前值至少是 dp[i-1],因为 s[i] 一定可以单独翻译cur = dp[i - 1]# 看一看 s[i-1,i] 是不是可以翻译if 9 < int(s[i - 1:i + 1]) < 26:if i - 2 < 0:# 12cur += 1else:# 要考虑到数组下标越界问题cur += dp[i - 2]dp[i] = curreturn dp[l - 1]

LeetCode 第 91 题:解码方法

传送门:91. 解码方法。

一条包含字母 A-Z 的消息通过以下方式进行了编码:

'A' -> 1
'B' -> 2
...
'Z' -> 26

给定一个只包含数字的非空字符串,请计算解码方法的总数。

示例 1:

输入: "12"
输出: 2
解释: 它可以解码为 "AB"(1 2)或者 "L"(12)。

示例 2:

输入: "226"
输出: 3
解释: 它可以解码为 "BZ" (2 26), "VF" (22 6), 或者 "BBF" (2 2 6) 。

Python 代码:

# 91、解码方法
# 一条包含字母 A-Z 的消息通过以下方式进行了编码:
#
# 'A' -> 1
# 'B' -> 2
# ...
# 'Z' -> 26
# 给定一个只包含数字的非空字符串,请计算解码方法的总数。class Solution:def numDecodings(self, s):""":type s: str:rtype: int"""l = len(s)if l == 0:return 0if l == 1:return 1 if s[0] != '0' else 0dp = [0 for _ in range(l)]dp[0] = 1 if s[0] != '0' else 0for i in range(1, l):if s[i] != '0':# 如果不是 '0' ,那么 s[i] 就可以编码,所以 cur 就至少是  dp[i-1]dp[i] += dp[i - 1]if 9 < int(s[i - 1:i + 1]) < 27:# 可以和前面的数字组成一个编码if i - 2 < 0:# 12dp[i] += 1else:dp[i] += dp[i - 2]return dp[l - 1]if __name__ == '__main__':test_str = '12's = Solution()res = s.numDecodings(test_str)print(res)

第 47 题:礼物的最大价值

传送门:礼物的最大价值。

在一个 m×n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。

你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格直到到达棋盘的右下角。

给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?

注意:

  • m,n>0

样例:

输入:

[[2,3,1],[1,7,1],[4,6,1]
]

输出:19

解释:沿着路径 2→3→7→6→1 可以得到拿到最大价值礼物。

思路:动态规划。礼物要么来自左边一格,要么来自上面一格,两者取最大。要特殊判断的就是边界情况。另外可以使用一维数组完成动态规划。如果可以修改 grid,直接在 grid 上修改就可以了,不用辅助空间。

Python 代码:

class Solution(object):def getMaxValue(self, grid):""":type grid: List[List[int]]:rtype: int"""m = len(grid)if m == 0:return 0n = len(grid[0])dp = [None for _ in range(n)]dp[0] = grid[0][0]for i in range(1, n):dp[i] = dp[i - 1] + grid[0][i]for i in range(1, m):for j in range(n):if j == 0:dp[j] += grid[i][0]else:dp[j] = grid[i][j] + max(dp[j - 1], dp[j])return dp[n - 1]

第 48 题:最长不重复字符串的子字符串

传送门:最长不含重复字符的子字符串。

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

假设字符串中只包含从’a’到’z’的字符。

样例:

输入:“abcabc”

输出:3

思路1:滑动窗口:

Python 代码:

class Solution:def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""# 特判size = len(s)if size < 2:return sizel = 0r = -1counter = [0 for _ in range(256)]res = 1while l < size:# 首先"右指针"不断向右边尝试,走到出现重复的最右边while r + 1 < size and counter[ord(s[r + 1])] == 0:# 表示没有重复元素,r 可以加 1counter[ord(s[r + 1])] += 1r += 1# 此时,记录不重复子串是"左指针"固定时候最长res = max(res, r - l + 1)# 考虑移动"左指针"# 此时 s[r+1] 就是已经扫过的区间里重复的元素,要把它剔除出去while r + 1 < size and s[l] != s[r + 1]:# 有重复元素,左边就要减 1counter[ord(s[l])] -= 1l += 1# 出了上一个循环以后,还要再把左指针向右移动一格,否则右指针不能向右移动counter[ord(s[l])] -= 1l += 1return res

思路2:动态规划

Python 代码:

class Solution:def lengthOfLongestSubstring(self, s):""":type s: str:rtype: int"""# 特判l = len(s)if l < 2:return l# dp[i] 表示以 s[i] 结尾的最长不重复子串的长度# 因为自己肯定是不重复子串,所以初始值设置为 1dp = [1 for _ in range(l)]map = dict()map[s[0]] = 0for i in range(1, l):if s[i] in map:if i - map[s[i]] > dp[i - 1]:dp[i] = dp[i - 1] + 1else:dp[i] = i - map[s[i]]else:dp[i] = dp[i - 1] + 1# 设置字符与索引键值对map[s[i]] = i# 最后拉通看一遍最大值return max(dp)

思路3:隔板法

Python 代码:

class Solution:def lengthOfLongestSubstring(self, s):# 特判l = len(s)if l < 2:return l# 隔板法# key:字符,val 出现的索引map = dict()point = 0res = 1for i in range(l):# 关键1:map[s[i]] >= point,等于是可以的if s[i] in map and map[s[i]] >= point:# 先把隔板向后移动一位point = map[s[i]] + 1# 然后记录最长不重复子串的长度res = max(res, i - point + 1)# 关键2:无论如何都更新位置map[s[i]] = ireturn res

参考资料:LeetCode 第 3 题:最长不重复字符串。

第 49 题:丑数

传送门:丑数。

把只包含因子 222、333 和 555 的数称作丑数(Ugly Number)。

例如 666、888 都是丑数,但 141414 不是,因为它包含因子 777。

求按从小到大的顺序的第 NNN 个丑数。

样例:

输入:5

输出:5

注意:习惯上我们把 111 当做是第一个丑数。

同 LeetCode 第 264 题,题解传送门:LeetCode 上的丑数问题。

思路:所谓的一个数 mmm 是另一个数 nnn 的因子,是指 nnn 能被 mmm 整除,也就是 n%m==0n\%m==0n%m==0 成立。根据丑数的定义,丑数只能被 222、333 和 555 整除。根据丑数的定义,丑数应该是另一个丑数乘以 222、333 或者 555 的结果(111除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以 222、333 或者 555 得到的。

这个思路的关键问题在于怎样保证数组里面的丑数是排好序的。对乘以 222 而言,肯定存在某一个丑数 T2T2T2,排在它之前的每一个丑数乘以 222 得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以乘以 222 得到的结果都会太大。我们只需要记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个 T2T2T2。对乘以 333 和 555 而言,也存在着同样的 T3T3T3 和 T5T5T5。

Python 代码:

class Solution:def GetUglyNumber_Solution(self, index):# write code hereif index < 7:return indexres = [1, 2, 3, 4, 5, 6]t2, t3, t5 = 3, 2, 1for i in range(6, index):res.append(min(res[t2] * 2, min(res[t3] * 3, res[t5] * 5)))while res[t2] * 2 <= res[i]:t2 += 1while res[t3] * 3 <= res[i]:t3 += 1while res[t5] * 5 <= res[i]:t5 += 1return res[index - 1]

第 50-1 题:字符串中第一个只出现一次的字符

传送门:字符串中第一个只出现一次的字符。

在字符串中找出第一个只出现一次的字符。

如输入"abaccdeff",则输出b

如果字符串中不存在只出现一次的字符,返回#字符。

样例:

输入:"abaccdeff"

输出:'b'

同 LeetCode 第 387 题,传送门:字符串中的第一个唯一字符。

思路:特别容易想到的思路,就是统计词频,统计词频可以用哈希表,也可以用数组。

Python 代码:

class Solution:def firstNotRepeatingChar(self, s):""":type s: str:rtype: str"""if len(s) < 1:return '#'counter = [0 for _ in range(256)]for alpha in s:counter[ord(alpha)] += 1for alpha in s:if counter[ord(alpha)] == 1:return alpha# 要注意:如果是 "aabbcc" 这种所有的字符都出现不止 1 次,# 就按照题意,返回 '#'return '#'

第 50-2 题:字符流中第一个不重复的字符

传送门:字符流中第一个只出现一次的字符。

请实现一个函数用来找出字符流中第一个只出现一次的字符。

例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。

当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。

如果当前字符流没有存在出现一次的字符,返回#字符。

样例:

输入:"google"

输出:"ggg#ll"

解释:每当字符流读入一个字符,就进行一次判断并输出当前的第一个只出现一次的字符。

Python 代码:使用辅助数组,做字母频数统计

class Solution:def __init__(self):self.chars = [0 for _ in range(256)]self.strs = []def firstAppearingOnce(self):""":rtype: str"""for char in self.strs:if self.chars[ord(char)] == 1:return charreturn '#'def insert(self, char):""":type char: str:rtype: void"""self.chars[ord(char)] += 1self.strs.append(char)

Java 代码:

Python 代码:

Python 代码:

class Solution:h = {}r = []def firstAppearingOnce(self):while len(Solution.r):if Solution.h[Solution.r[0]] == 1:return Solution.r[0]Solution.r = Solution.r[1:]return '#'def insert(self, char):Solution.h[char] = Solution.h.get(char, 0) + 1if Solution.h[char] == 1:Solution.r.append(char)

作者:applezjm
链接:https://www.acwing.com/activity/content/code/content/19320/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

(本节完)

《剑指 Offer》(第 2 版) 题解(Python 语言实现)第 41-50 题相关推荐

  1. 【剑指offer】java版题解(持续更新)

    本文为刷[剑指]备战校招的过程,持续更新 备战虽晚但卷,共勉! 目录,按刷题时间排序 斐波那契数列 用两个栈实现队列 二维数组中的查找 包含min函数的栈 从尾到头打印链表 反转链表 复杂链表的复制 ...

  2. 剑指offer第2版Python题解(更新中)

    O(n^2)排序 冒泡排序.插入排序与选择排序(Python)_NLP_victor的博客-CSDN博客 归并 归并排序(Python)_NLP_victor的博客-CSDN博客 快排 快速排序(Py ...

  3. 剑指offer(第二版)读书笔记以及编程题目python版答案(二)

    剑指offer(第二版)读书笔记以及编程题目python版答案(二) 题目五:青蛙跳台阶 github地址: https://github.com/ciecus/leetcode_answers/tr ...

  4. 【剑指offer】Java版代码(完整版)

    参考链接 [剑指offer]Java版代码(完整版)

  5. 剑指offer 矩阵中的路径 @python

    剑指offer 矩阵中的路径 @python 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向 ...

  6. 剑指Offer(第二版)面试题56:数组中数字出现的次数

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/73609133冷血之心的博客) 剑指Offer(第二版)面试题56: ...

  7. 《剑指offer》面试题的Python实现

    所属网站分类: 面试经典 > python 作者:gg 链接: http://www.pythonheidong.com/blog/article/464/ 来源:python黑洞网 www.p ...

  8. 剑指Offer(JS版)

    字符串的排列 题目描述: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. ...

  9. 剑指offer:java版

    作者:CyC2018 链接:https 文章目录 一.基础 3.数组中的重复的数字 4. 二维数组中的查找 5. 替换空格 6. 从尾到头打印链表 7. 重建二叉树 8. 二叉树的下一个结点 9. 用 ...

  10. LeetCode刷题 _「剑指 Offer]专项突破版

    第01天 整数 剑指 Offer II 001. 整数除法 class Solution:# 时间复杂度:O(logn), 空间复杂度:O(1)def divideCore(self, dividen ...

最新文章

  1. Linux主辅DNS数据不同步故障排除
  2. Cisco Catalyst交换机密码恢复策略
  3. BCI比赛数据集简介-BCI competition IV 2b
  4. 用Java API实现HDFS操作(三)问题汇总
  5. 微型计算机寻址方式命令,寻址方式与基本指令-微机原理实验报告.docx
  6. Hello Blazor:(1)像ASP.NET WebForm一样写代码
  7. js正则函数match、exec、test、search、replace、split使用集合
  8. java基本数据类型的标识符_java基础(一)-标识符、变量、基本数据类型及转换、运算符及表达式...
  9. 简述java中类的构造方法_Java中类的构造方法
  10. 爬虫练习--爬取CNNVD相关漏洞
  11. ipad air1 12.5.5 checkra1n 越狱+绕过ID
  12. 调节效应分析时简单斜率图或交互效应图出现负数截距?
  13. uniapp教程,uni-app教程
  14. 赴日工作之在留换签证
  15. tablueau地图标记圆形_多点钉图标记-简单易用的地图位置标记标注工具
  16. 畅邮(DM Pro)-一款强悍、纯净而稳定的重量级电子邮箱客户端(支持分发、追踪)...
  17. 1个免费网站教你如何追踪微信实时热点,速速收藏
  18. C++的get()函数与getline()函数使用详解
  19. 纯css实现向上箭头动画显示
  20. 对驱动器盘符和卷名的认识

热门文章

  1. 关于多元线性回归显著性水平P的理解
  2. gparted分区教程
  3. 高斯消元法python编程_高斯消元法的Python实现
  4. 形形色色的图片格式详解
  5. 科技云报道:疫情三年,数字会展成色几何?
  6. 南昌计算机考研学校比较好,南昌排名前十的考研寄宿学校
  7. 怎么用微软云盘自动备份文件_微软通过自动更新打破了Windows 10的文件关联
  8. 当你选择编程语言时你在选择什么
  9. win10 下GO语言环境的搭建
  10. win10安装go开发环境