数据结构与算法之字符串

基于字符计数的问题

 一、偶数字串的数量**********************

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] = *

posted @ 2020-05-11 23:13  LinBupt  阅读(268)  评论(0)    收藏  举报