字符串

一、基于字符计数的问题

1.偶数子串的数量
ž 给定一串0到9的数字。任务是计算在将整数转换为偶数时的子串的数量。
ž Input : str = "1234".
ž Output : 6
ž “2”, “4”, “12”, “34”, “234”, “1234是6个子字符串,它们是偶数。
def evenNum(s):
    count = 0
    for i in range(len(s)):
        if int(s[i]) % 2 == 0:
            count += i + 1
    return count

2.学生出勤记录

ž 给你一个代表学生出勤记录的字符串。 该记录只包含以下三个字符:
ž 'A' : 缺席.
ž 'L' : 迟到.
ž 'P' : 出席.
ž 如果学生的出勤记录不包含多于一个“A”(缺席)或超过两个连续的“L”(迟
到),则可以获得奖励。
ž 你需要根据他的出勤记录来返回学生是否可以得到奖励。
def checkRecord(self, s):
    return not (s.count('A') > 1 or 'LLL' in s)

3.对具有相同首尾字符的子字符进行计数

ž 给出一个字符串S,我们需要找到所有连续的子字符串开始和结束的字符都相同的
计数。
ž Input : S = "abcab"
ž Output : 7
ž "abcab" 有15个子字符串
ž 在上面的子串中,有7个子串满足要求:a,abca,b,bcab,c,a和b。.
方法一:暴力
def countSub(s):
    result = 0
    for i in range(len(s)):
        for j in range(i, len(s)):
            if (s[i] == s[j]):
                result += 1
    return result

方法二:

from collections import Counter

def countSub(s):
    counter = Counter(s)
    result = 0
    for x in counter:
        result += counter[x] * (counter[x] + 1) // 2
        
    return result

4.计数问题 IV

ž 字符串中最大连续重复字符
ž 给定一个字符串,其任务是在字符串中查找最大连续重复字符。
def maxRepeating(s):
    n = len(s)
    count = 0
    result = s[0]
    local = 1
    
    for i in range(n):
        if (i < n - 1 and s[i] == s[i+1]):
            local += 1
        else:
            if (local > count):
                count = local
                result = s[i]
            local = 1
    return result

5.排序数组中删除重复

def removeDuplicates(A):
    if not A:
        return 0

    newTail = 0
    for i in range(1, len(A)):
        if A[i] != A[newTail]:
            newTail += 1
            A[newTail] = A[i]
            
    for j in range(newTail + 1, len(A)):
        A[j] = 'X'

    print(A)
    return newTail + 1

二、同字母异序

1.同字母异序词

ž 编写一个函数来检查两个给定的字符串是否彼此是相同字母异序词。 一个字符串的相同字
母异序词是另一个包含相同字符的字符串,只有字符的顺序可以不同。 例如,“abcd”和
“dabc”是彼此的相同字母异序词。
方法一:排序
def areAnagram(str1, str2):
    if len(str1) != len(str2):
        return False
    return sorted(str1) == sorted(str2)

方法二:

from collections import Counter

def areAnagram(str1, str2):
    return Counter(str1) == Counter(str2)

2.同字母异序词 II

ž 查找字符串中的所有相同字母异序词
ž 给定字符串s和非空字符串p,在s中找到所有p的相同字母异序词的起始索引。
ž 字符串只包含小写英文字母,字符串s和p的长度不会超过20,100。
ž 输出的顺序并不重要。
ž Input:
s: "cbaebabacd" p: "abc"
ž Output: [0, 6]
ž 解释:
ž 以0作为起始索引 的子序列是 “cba”,它是"abc"的相同字母异序词.
ž 以6作为起始索引 的子序列是 “bac”,它是"abc"的相同字母异序词.
from collections import Counter

def findAnagrams(s, p):
    res = []
    pCounter = Counter(p)
    sCounter = Counter(s[:len(p) - 1])
    for i in range(len(p) - 1,len(s)):
        sCounter[s[i]] += 1   # include a new char in the window
        if sCounter == pCounter:    # This step is O(1), since there are at most 26 English letters 
            res.append(i-len(p)+1)   # append the starting index
        sCounter[s[i-len(p)+1]] -= 1   # decrease the count of oldest char in the window
        if sCounter[s[i-len(p)+1]] == 0:
            del sCounter[s[i-len(p)+1]]   # remove the count if it is 0
    return res

3.查找同字母异序词的映射

ž 给定两个列表A和B,B是A的一个同字母组。这意味着B是通过随机化A中元素的顺
序而创建的。
ž 我们希望找到一个从A到B的索引映射P。映射P [i] = j意味着列表A中的第i个元
素出现在B的索引为j的位置。
ž 这些列表A和B可能包含重复项。 如果有多个答案,则输出它们中的任意一个。
ž 例如,给定
ž A = [12, 28, 46, 32, 50]
ž B = [50, 12, 32, 46, 28]
ž 应当返回[1, 4, 3, 2, 0]
ž P[0] = 1因为A的第0个元素出现在B[1]处,并且P[1] = 4,因为A的第1个元素出
现在B [4]处,依此类推。
方法一:O(N2)
def anagramMappings1(A, B):
    answer = []
    for a in A:
        for i,b in enumerate(B):
            if a == b:
                answer.append(i)
                break
    return answer

另:

def anagramMappings2(A, B):
    return [B.index(a) for a in A]

方法二:O(N)

def anagramMappings3(A, B):
    d = {}
    for i,b in enumerate(B):
        d[b] = i
    return [d[a] for a in A]

三、回文

1.移位
ž 给定两个字符串s1和s2,写一段程序说明s2是否是s1 的移位。
def areRotations(string1, string2):
    size1 = len(string1)
    size2 = len(string2)

    if size1 != size2:
        return 0
 
    temp = string1 + string1
 
    return temp.count(string2) > 0

2.移位 II

ž 写一个函数 rotate(arr[], d, n) 将大小为n的数组arr[] 移位d个单位。
def reverse(arr, start, end):
    while start < end:
        arr[start], arr[end] = arr[end], arr[start]
        start += 1
        end -= 1

def rotate(arr, d):
    n = len(arr)
    reverse(arr, 0, d - 1)
    reverse(arr, d, n - 1)
    reverse(arr, 0, n - 1)

3.回文数

ž 判断一个整数是否是回文数。当一个整数从前从后读一样时可判定为回文数。
def isPalindrome(s):
    return s == s[::-1]
def isPalindrome(s):
    for i in range(len(s) // 2):
        if s[i] != s[- 1 - i]:
            return False

    return True

判断整数:

def isPalindrome(x):
    if x < 0:
        return False

    ranger = 1
    while x // ranger >= 10:
        ranger *= 10
    print(ranger)
    while x:
        left = x // ranger
        right = x % 10
        if left != right:
            return False

        x = (x % ranger) // 10
        ranger //= 100

    return True

4.移位回文

ž 检查给定的字符串是否是一个回文字符串的移位。
def isRotationOfPalindrome(s):
 
    # If string itself is palindrome
    if isPalindrome(s):
        return True
 
    # Now try all rotations one by one
    n = len(s)
    for i in range(len(s) - 1):
        s1 = s[i+1:n]
        s2 = s[0:i+1]
 
        # Check if this rotation is palindrome
        s1 += s2
        if isPalindrome(s1):
            return True
 
    return False

另:

def isRotationOfPalindrome(s):
    n = len(s)
    s = s + s
    for i in range(n):
        if isPalindrome(s[i : i + n]):
            return True
    return False
ž 5.重排回文
ž 给定一个字符串,检查字符串中的各字符是否可以构成一个回文字符串。
from collections import Counter
def canRearrage(s):
    odd = 0
    counter = Counter(s)
    for key in counter.keys():
        if counter[key] % 2 == 1:
            odd += 1
        if odd > 1:
            return False
    return True

6.最长回文

ž 给定一个由大小写字母组成的字符串,找到可由这些字符构成的最长的回文字符串。
ž 本例是大小写敏感的,例如“Aa”在此处不被认为是回文字符串。
from collections import Counter
def longestPalindrome(s):
    ans = 0
    counter = Counter(s)
    for key in counter.keys():
        v = counter[key]
        ans += v // 2 * 2
        if ans % 2 == 0 and v % 2 == 1:
            ans += 1
    return ans

7.回文流判定

# d is the number of characters in input alphabet
d = 256
 
# q is a prime number used for evaluating Rabin Karp's
# Rolling hash
q = 103
 
def checkPalindromes(string):
 
    # Length of input string
    N = len(string)
 
    # A single character is always a palindrome
    print(string[0] + " Yes")
 
    # Return if string has only one character
    if N == 1:
        return
 
    # Initialize first half reverse and second half for
    # as firstr and second characters
    firstr = ord(string[0]) % q
    second = ord(string[1]) % q
 
    h = 1
    i = 0
    j = 0
 
    # Now check for palindromes from second character
    # onward
    for i in range(1,N):
 
        # If the hash values of 'firstr' and 'second'
        # match, then only check individual characters
        if firstr == second:
 
            # Check if str[0..i] is palindrome using
            # simple character by character match
            for j in range(0,i//2):
                if string[j] != string[i-j]:
                    break
            j += 1
            if j == i//2:
                print(string[i] + " Yes")
            else:
                print(string[i] + " No")
        else:
            print(string[i] + " No")
 
        # Calculate hash values for next iteration.
        # Don't calculate hash for next characters if
        # this is the last character of string
        if i != N-1:
 
            # If i is even (next i is odd)
            if i % 2 == 0:
 
                # Add next character after first half at
                # beginning of 'firstr'
                h = (h*d) % q
                firstr = (firstr + h*ord(string[i//2]))%q
 
                # Add next character after second half at
                # the end of second half.
                second = (second*d + ord(string[i+1]))%q
            else:
                # If next i is odd (next i is even) then we
                # need not to change firstr, we need to remove
                # first character of second and append a
                # character to it.
                second = (d*(second + q - ord(string[(i+1)//2])*h)%q
                            + ord(string[i+1]))%q

 

 
 
posted @ 2020-05-30 10:52  oldby  阅读(216)  评论(0编辑  收藏  举报