数据结构与算法之字符串
基于字符计数的问题
一、偶数字串的数量**********************
Given a string of digits 0 – 9. The task is to count number of substrings which when convert into integer form an even number.
Input : str = "1234".
Output : 6
"2", "4", "12", "34", "234", "1234" are 6 substring which are even.
Input : str = "154".
Output : 3
Input : str = "15".
Output : 0
1 def evenNum(s): 2 count = res = 0 3 for i in s: 4 if i == 0: 5 count += 1 6 if i % 2 == 0: 7 res += i + 1 - count 8 return res
二、学生出勤记录
给一个代表学生出勤记录的字符串,该记录只包含以下三个字符:
A:缺席 L:迟到 P:出席
如果学生的出勤记录不包含多于一个A或超过两个连续的L,则可以获得奖励。
1 def isprise(s): 2 count1 = count2 = 0 3 for i in range(len(s)): 4 if s[i] == 'A': 5 count1 += 1 6 if count1 == 2: 7 return False 8 if s[i] == 'L': 9 if s[i-1] != 'L': 10 count2 = 0 11 count2 += 1 12 if count2 > 2: 13 return False 14 return True
1 #Python s.count('A')-->O(n) 2 def checkRecord(s): 3 return not (s.count('A') > 1 or 'LLL' in s)
三、对具有相同首尾字符的连续子字符串进行计数
给出一个字符串S,找到所有连续的子字符串,其开始和结束的字符都相同
We are given a string S, we need to find count of all contiguous substrings starting and ending with same character.
Input : S = "abcab"
Output : 7
There are 15 substrings of "abcab"
Out of the above substrings, there are 7 substrings : a, abca, b, bcab, c, a and b.
1 from collections import Counter 2 def countSub(s): 3 counter = Counter(s) 4 res = 0 5 for x in counter: 6 res += counter[x] * (counter[x]+1)//2 7 return res
四、字符串中最大连续重复字符
给定一个字符串,在字符串中查找最大连续重复字符
Given a string, the task is to find maximum consecutive repeating character in string.
1 def maxRepeating(s): 2 count = 0 3 n = len(s) 4 res = s[0] 5 local = 1 6 for i in range(n): 7 if i < n-1 and s[i] == s[i+1]: 8 local += 1 9 else: 10 if local > count: 11 count = local 12 res = s[i] 13 local = 1 14 return res
五、在排序数组中删除重复
双指针
1 def removeDuplicates(A): 2 if not A: 3 return 0 4 newTail = 0 5 for i in range(1, len(A)): 6 if A[i] != A[newTail]: 7 newTail += 1 8 A[newTail] = A[i] 9 for j in range(newTail+1, len(A)): 10 A[j] = 'X' 11 return newTail + 1
同字母异序:排序、字典/Counter、双指针
一、Anagrams
Write a function to check whether two given strings are anagram of each other or not. An anagram of a string is another string that contains same characters, only the order of characters can be different. For example, “abcd” and “dabc” are anagram of each other.
1 def areAnagram(s1, s2): 2 if len(s1) != len(s2): 3 return False 4 return sorted(s1) == sorted(s2)
1 from collections import Counter 2 def areAnagram(s1, s2): 3 return Counter(s1) == Counter(s2)
二、Find All Anagrams in a String
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
The order of output does not matter.
Input:
s: "cbaebabacd" p: "abc"
Output:
[0, 6]
Explanation:
The substring with start index = 0 is "cba", which is an anagram of "abc".
The substring with start index = 6 is "bac", which is an anagram of "abc".
1 from collections import Counter 2 def findAnagrams(s, p): 3 res = [] 4 pCounter = Counter(p) 5 sCounter = Counter(s[len(p)-1]) 6 for i in range(len(p)-1, len(s)): 7 sCounter[s[i]] += 1 8 if sCounter == pCounter: 9 res.append(i - len(p) + 1) 10 sCounter[s[i-len(p)+1]] -= 1 11 if sCounter[s[i-len(p)+1]] == 0: 12 del sCounter[s[i-len(p)+1]] 13 return res
三、Find Anagram Mappings
Given two lists Aand B, and B is an anagram of A. B is an anagram of A means B is made by randomizing the order of the elements in A.
We want to find an index mapping P, from A to B. A mapping P[i] = j means the ith element in A appears in B at index j.
These lists A and B may contain duplicates. If there are multiple answers, output any of them.
For example, given
A = [12, 28, 46, 32, 50]
B = [50, 12, 32, 46, 28]
We should return
[1, 4, 3, 2, 0]
as P[0] = 1 because the 0th element of A appears at B1, and P1 = 4 because the 1st element of A appears at B[4], and so on.
1 def anagramMappings(A, B): 2 dic = {} 3 for ind, val in enumerate(B): 4 dic[val] = i 5 return [dic[a] for a in A]
回文:rotation、counter
一、移位
给定两个字符串s1和s2,判断s2是否是s1的移位
1 def areRotations(s1, s2): 2 size1 = len(s1) 3 size2 = len(s2) 4 if size1 != size2: 5 return 0 6 temp = s1 + s1 7 return temp.count(s2) > 0
二、移位Ⅱ
将大小为n的数组移动d个单位
1 # 三段反转 左移 2 def reverse(arr, start, end): 3 while start < end: 4 arr[start], arr[end] = arr[end], arr[start] 5 start += 1 6 end -= 1 7 def rotate(arr, d): 8 n = len(arr) 9 reverse(arr, 0, d-1) 10 reverse(arr, d, n-1) 11 reverse(arr, 0, n-1)
# 右移 def reverse(arr, start, end): while start < end: arr[start], arr[end] = arr[end], arr[start] start += 1 end -= 1 def rotation(arr, d): n = len(arr) reverse(arr, 0, n-d-1) reverse(arr, n-d-1, n-1) reverse(arr, 0, n-1)
三、回文
判断一个字符串是否是回文
1 def reverse(s): 2 return s[::-1] 3 def isPalindrome(s): 4 rev = reverse(s) 5 if s== rev: 6 return True 7 return False
四、数字回文
判断一个整数是否是回文数
1 def intPalindrome(n): 2 return str(n) == str(n)[::-1]
1 def isPalindrome(x): 2 if x < 0: 3 return False 4 ranger = 1 5 while x // ranger >= 10: 6 ranger *= 10 7 while x: 8 left = x // ranger 9 right = x % 10 10 if left != right: 11 return False 12 x = (x % ranger) // 10 13 ranger //=100 14 return True
五、移位回文
判断给定的字符串是否是一个回文的移位
1 def isRotationOfPalindrome(s): 2 n = len(s) 3 s = s + s 4 for i in range(n): 5 if isPalindrome(s[i:i+n]): 6 return True 7 return False
六、重排回文
给定一个字符串,检查字符串中的各字符是否可以构成一个回文字符串
1 from collections import Counter 2 def canRearrange(s): 3 odd = 0 4 counter = Counter(s) 5 for key in counter.keys(): 6 if counter[key] % 2 == 1: 7 odd += 1 8 if odd > 1: 9 return False 10 return True
七、最长回文
给定一个由大小写字母组成的字符串,找到可由这些字符构成的最长的回文字符串
1 from collections import Counter 2 def longestPalindrome(s): 3 ans = 0 4 counter = Counter(s) 5 for key in counter.keys(): 6 v = counter[key] 7 ans += v // 2 * 2 8 if ans % 2 == 0 and v % 2 == 1: 9 ans += 1 10 return ans
八、最长子回文串(LeetCode 5)
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
找长度为1的-->找长度为2的-->找长度为3以上的
1 class Solution: 2 def longestPalindrome(self, s: str) -> str: 3 if not s or len(s) == 0: 4 return s 5 dp = [[False for _ in range(len(s))] for _ in range(len(s))] 6 start = 0 7 max_len = 1 8 for i in range(len(s)): 9 dp[i][i] = True 10 if i + 1 < len(s) and s[i] == s[i+1]: 11 dp[i][i+1] = True 12 start = i 13 max_len = 2 14 for l in range(3, len(s)+1): 15 for i in range(len(s) - l + 1): 16 r = i + l - 1 17 if s[i] == s[r] and dp[i+1][r-1]: 18 dp[i][r] = True 19 start = i 20 max_len = l 21 return s[start:start+max_len]
九、回文流
heap-->数据流取中位数,minHeap+maxHeap
二进制字符串
子序列
一、最长子序列
给定一个字符串s和一个整数k,找到其他字符串t,使得t是给定字符串s的最大子序列,同时t的每个字符在字符串s中必须至少出现k次
1 from collections import Counter 2 def longestSub(s, k): 3 res = list() 4 c = Counter(s) 5 for i in s: 6 if c[i] >= k: 7 res.append(i) 8 return "".join(res)
二、检查子序列
给定两个字符串s1和s2,确定s1是否是s2的子序列。子序列是可以通过删除一些元素而不改变其余元素的顺序从另一个序列派生的序列。
1 #递归 2 def isSubSequence(s1, s2, m, n): 3 if m == 0: 4 return True 5 if n == 0: 6 return False 7 if s1[m-1] == s2[n-1]: 8 return isSubSequence(s1, s2, m-1, n-1) 9 return isSubSequence(s1, s2, m, n-1)
1 # 双指针 2 def isSubSequence(s1, s2): 3 m = len(s1) 4 n = len(s2) 5 j = 0 6 i = 0 7 while j < m and i < n: 8 if s1[j] == s2[i]: 9 j += 1 10 i += 1 11 return j == m
三、通过删除给定字符串的字符得到字典中最长的单词
给一个字典和一个字符串,找到字典中最长的字符串,它可以通过删除给定的字符串中的一些字符来形成
1 def findLongestString(words, s): 2 res = "" 3 length = 0 4 for w in words: 5 if length < len(w) and isSubSequence(w, s): 6 res = w 7 length = len(w) 8 return res
四、找出所有子序列元素之和的和
subset-->2**n 每一个数字出现的次数是2**(n-1)
1 def sumSub(arr): 2 ans = sum(arr) 3 return ans * pow(2, len(arr)-1)
五、模式搜索
strStr 字符串匹配算法
python-->find index
1 def find(text, pattern): #O(n**2) 2 for i in range(len(text)-len(pattern)+1): 3 if text[i:i+len(pattern)] == pattern: 4 return i 5 return -1
1 def strStr(text, pattern): 2 n, m = len(text), len(pattern) 3 for i in range(n - m + 1): 4 start = i 5 for j in range(len(pattern)): 6 if text[i] != pattern[j]: 7 break 8 i += 1 9 else: 10 return start 11 return -1
1 #Rolling Hash -->Hash+Sliding Window 2 #Horner's Rule -->abc:(axp+b)xp+c a+bp+cp**2 O(n) 3 def strStr(text, pattern): 4 base = 29 5 patternHash = 0 6 tempBase = 1 7 hayHash = 0 8 for i in range(len(pattern)-1, -1, -1): 9 patternHash += ord(pattern[i]) * tempBase 10 tempBase *= base 11 12 tempBase = 1 13 for i in range(len(pattern)-1, -1, -1): 14 hayHash += ord(text[i]) * tempBase 15 tempBase *= base 16 17 if patternHash == hayHash and text[0:len(pattern)] == pattern: 18 return 0 19 20 tempBase /= base 21 for i in range(len(pattern), len(text)): 22 hayHash = (hayHash - ord(text[i-len(pattern)]) * tempBase])) * base + ord(text[i]) 23 if hayHash == patternHash and text[i-len(pattern)+1:i+1] == pattern: 24 return i - len(pattern) + 1 25 return -1
六、敏感词
字典+split
For the given sentence as input, censor a specific word with asterisks ‘*’
def censor(text, word): word_list = text.split() result = ' ' stars = '*' * len(word) count = 0 index = 0 for i in word_list: if i == word: word_list[index] = stars index += 1 result = ' '.join(word_list) return result
七、用C替换所有出现的字符串AB
1 def translate(st): 2 l = len(st) 3 if l < 2: 4 return 5 i = 0 6 j = 0 7 while j < i - 1: 8 if st[j] == 'A' and st[j+1] == 'B': 9 j += 2 10 st[i] = 'C' 11 i += 1 12 continue 13 st[i] = st[j] 14 i += 1 15 j += 1 16 if j == l-1: 17 st[i] = st[j] 18 i += 1 19 return i
八、Count of Occurrences of “1(0+)1” Pattern
Given an alphanumeric string, find the number of times a pattern 1(0+)1 occurs in the given string. Here, (0+) signifies the presence of non empty sequence of consecutive 0’s.
1 def patternCount(s): 2 last = s[0] 3 i = 1 4 counter = 0 5 while i < len(s): 6 if s[i] =='0' and last == '1': 7 while i < len(s) and s[i] == '0': 8 i += 1 9 if i == len(s): 10 return counter 11 if s[i] == '1': 12 counter += 1 13 last = s[i] 14 i += 1 15 return counter
九、与通配符匹配的字符串
* 0个或者多个
?1个
Given two strings where first string may contain wild card characters and second string is a normal string. Write a function that returns true if the two strings match. The following are allowed wild card characters in first string.
* --> Matches with 0 or more instances of any character or set of characters.
? --> Matches with any one character.
T(i,j) string里面的前i个字符和pattern里面的前j个字符是否是match
T(i, j) = False if s[i] != p[j]
T(i, j) = T(i-1, j-1) if s[i] == p[j]
T(i, j) = T(i-1, j-1) if p[j] = ?
T(i, j) = T(i, j-1) or T(i-1, j) if p[j] = *

浙公网安备 33010602011771号