算法之字符串
1. 偶数字串的数量 给定一串0-9的数字字符串, 计算在将整数转换为偶数时的字串数量 input: str = ‘1234’ output:6 有2 12 34 234 1234 这6个字符串,他们是偶数 题解: 找出偶数所在的位置, 则之前的字符都能和字符可以构成偶数, 有 i + 1 个 注意: Python 中for循环时, 注意是需要索引还是迭代对象中的值 def even_nums(s): if len(s) == 0: return 0 count = 0 for i in range(len(s)): if int(s[i]) % 2 == 0: count = count + i + 1 return count 2. 学生出勤记录 给定一个代表学生出勤的字符串, 该记录只包括以下三个字符 A: 缺席 L: 迟到 P: 出现 如果学生的出勤记录不包含多余一个A 或 不超过两个连续的L, 则可以获取奖金 根据出勤记录返回学生算法可以获得奖金 def if_get_award(s): count_L = 0 count_A = 0 for i in range(len(s)): if s[i] == 'A': count_A += 1 if s[i] == 'L' and i !=len(s)-1 and s[i+1] == 'L': count_L += 1 return not (count_A > 1 or count_L > 1) 3. 字符串中最大连续重复的字符 input: abaaaacddeff output: a def find_max_duplicate(s): count = 0 result = s[0] local = 1 # 临时变量计算 for i in range(len(s)): # 只需要比较相邻的两个的元素即可, # s[i]=s[i+1] , s[i+1]=s[i+2] ==> s[i]=s[i+2] if i < len(s)-1 and s[i] == s[i+1]: local += 1 else: if local > count: # 更新全局的计数变量 count = local result = s[i] local = 1 #重置local变量 return result 2. 查找同字母异序词的映射 给定两个列表A,B, B是A的一个同字母组,找出一个A到B的映射P,使得P[i] = j意味着列表A中的第i个元素在B的索引为j的位置 例如, 给定 A = [12, 28, 46, 32, 50] B = [50, 12, 32, 46, 28] 应当返回 [1, 4, 3, 2, 0] 解题思路: 使用dict def get_index(arra1, arra2): d = {item: index for index, item in enumerate(arra2)} return [d.get(i) for i in arra1] 1.2 写一个函数rotate(arr[], d, n)将大小为n的数组arr[] 移位d个单位 解题思路: 三次反转法 比如12345678,向右移动2位后变成78123456 三次反转法 第一次反转654321 0 到 d-1 第二次反转87 d 到 n-1 第三次将字符串整体反转 0 到 n-1 def move_num(s, n): if n > len(s):raise ValueError('参数非法') def reverse(s, start, end): while start < end: s[start], s[end] = s[end], s[start] start += 1 end -= 1 _len = len(s) reverse(s, 0, n - 1) reverse(s, n, _len - 1) reverse(s, 0, _len - 1) 判断一个整数(不是字符串)是否是回文数. 当一个整数从前从后读一样时可判定为回文数 整数%ranger = 最高位 整数 // 10 = 最定位 def is_palind(num): if num<0:return False # 获取最高位 ranger = 1 while num//ranger >= 10: ranger *= 10 print(ranger) while num: left = num//ranger # 最高位 right = num%10 # 最低位 if left !=right: return False # 修正num值,将最高位和最低位去掉 num = (num % ranger) // 10 # 修正ranger ranger = ranger // 10 return True 1.2 移动回文, 检查给定的字符串是否是一个回文字符串的移位 比如,s = 'aab', 移动两位后变成ada, ada是一个回文, 解题思路: 将两个s合并成一个字符串 s1 = 'aabaab' 在s1中判断是否有长度为3的回文字符串 def motion_palind(s): l = len(s) def reverse(s, start, end): s = list(s) while start < end: s[start], s[end] = s[end], s[start] start += 1 end -= 1 return ''.join(s) new_s = s + s for i in range(len(new_s) - l): temp = new_s[i:i+l] if temp == reverse(temp,0,len(temp)-1): return True return False 子序列 1.1 给定一个字符串s 和一个整数k, 找到其他字符串t, 使得 k 是给定字符串 s 的最大子序列, 同时 t的每个字符在字符串s中必须至少出现k次 input: s = 'baaabaacba' k = 3 output:baaabaaba c被舍弃 解题思路: a. 对s字符串所所以的字符进行计数 b. 遍历s, 如果字符大于k,则append到新的列表, 否则舍弃 def longest_sub(s, k): # 获取每一个字符出现的次数 d = {} for i in s: if d.get(i): d[i] = d.get(i) + 1 else: d[i] = 1 print(d) # 遍历字符串, 大于等于k的则append到新的列表中 new_s = [] for i in s: if d.get(i)>=k: new_s.append(i) return ''.join(new_s) 检查子序列 1. 给定两个字符串str1和str2, 确定str1是否是str2的子序列, 子序列是可以通过删除一些元素而不改变其余元素的顺序从另一个序列派生的序列 Input: str1 = 'AXY' str2 = 'ADXCPY' output: True Input: str1 = 'AXY' str2 = 'ADYCP' output: False 解题思路: 双指针 def is_sub_sequence(s1, s2): # s1 是否是 s2的子字符串 m = len(s1) n = len(s2) i = 0 # 字串s1的指针 j = 0 # 字符串s2的指针 while i < m and j < n: if s1[i] == s2[j]: i += 1 j += 1 else: j += 1 return i == m # 字串s1的指针遍历到长度m, 则说明找到了字串