LeetCode -- string (python language)

Posted by deadimp on Sat, 05 Mar 2022 11:50:54 +0100

LeetCode -- string (python language)

1, String

1.1 string definition

A string is a concatenation of a series of characters. The string can be traversed, and each traversal is a character.

1.2 string matching

First, we call the string to be matched (long) as the main string, and the string to be matched (short) as the sub string (pattern string). String matching is to find the position where the pattern string exists in the main string. String matching algorithms are mainly divided into (simple matching of / string) BF algorithm and (efficient matching of string) KMF algorithm. Due to the author's limited ability, a link from the boss is attached here. Difference between BF algorithm and KMF algorithm

2, Brush questions

Verification string 1.2 palindrome

Given a string, verify whether it is a palindrome string. Only alphanumeric characters are considered, and the case of letters can be ignored.
Note: in this topic, we define an empty string as a valid palindrome string.

Example 1:
Input: "A man, a plan, a canal: Panama"
Output: true
Explanation: "Amana planacanalpanama" is a palindrome string

Example 2:
Enter: "race a car"
Output: false
Explanation: "raceacar" is not a palindrome string

Tips:
1 <= s.length <= 2 * 105
The string s consists of ASCII characters

#Very conventional questions, first exclude non alphabetic and capitalized, compare whether it is symmetrical before and after, and the idea of double pointer
class Solution:
    def isPalindrome(self, s: str) -> bool:
        n = len(s)
        i = 0
        j = n - 1
        while(i<j):
            if not (s[i].isalnum()): #Exclude non alphabetic
                i += 1
                continue
            if not (s[j].isalnum()): #Non excluded letters
                j -= 1
                continue
            if((s[i].lower())==(s[j].lower())): #Case insensitive
                i += 1 
                j -= 1
            else:
                return False 
        return True
#	48 ms	15 MB

2.2 flip the words in the string

Give you a string s and flip all the words in the string one by one.
A word is a string of non whitespace characters. Use at least one space in s to separate words in the string.
Please return a string that flips the word order in s and connects it with a single space.

explain:
The input string s can contain extra spaces before, after, or between words.
After flipping, the words should be separated by only one space.
The flipped string should not contain additional spaces.

Example 1:
Input: s = "the sky is blue"
Output: "blue is sky the"

Example 2:
Input: S = "Hello world"
Output: "world hello"
Explanation: the input string can contain extra spaces before or after, but the flipped characters cannot be included.

Example 3:
Enter: s = "a good example"
Output: "example good a"
Explanation: if there is extra space between two words, reduce the space between words after flipping to only one.

Example 4:
Enter: S = "Bob loves Alice"
Output: "Alice Loves Bob"

Example 5:
Enter: s = "Alice does not even like bob"
Output: "bob like even not does Alice"

Tips:
1 <= s.length <= 104
s includes upper and lower case letters, numbers and spaces'
At least one word exists in s

Advanced:
Please try the in-situ solution of O(1) additional space complexity.

#Segmentation (remember to remove redundant spaces, do not find spaces once, check whether there are words stored), inversion, connection     
#2_1 
class Solution:
    def reverseWords(self, s: str) -> str:
        words = s.split() #Divide according to the space
        words.reverse() #inversion
        return " ".join(words) #connect
#36 ms	15 MB
#2_2
class Solution:
    def reverseWords(self, s: str) -> str:
        words = [] #Final text library
        cur = ""  #Store each word
        for ch in s: 
            if(ch==" "):#If it is a space, judge whether it is a word in front of it
                if cur:#It's a word. It's recorded
                    words.append(cur)#Add text library
                    cur = ""#Storage converted to empty
            else:
                cur += ch#Record each letter of the word
        if cur:
            words.append(cur)#Last word storage
        n = len(words)#Word count
        for i in range(n//2) Inversion: # similar to array, swap each word
            words[i],words[n-1-i] = words[n-1-i],words[i]
        #words.reverse() #Or reverse the list directly
        return " ".join(words)#Connect with spaces
#40 ms	15.1 MB

2.3 validate palindrome string II

Given a non empty string s, at most one character can be deleted. Determine whether it can be a palindrome string.

Example 1:
Input: s = "aba"
Output: true

Example 2:
Enter: s = "abca"
Output: true
Explanation: you can delete the c character.

Example 3:
Enter: s = "abc"
Output: false

Tips:
1 <= s.length <= 105
s consists of lowercase English letters

#When deleting a character can be considered
#3_1
class Solution:
    def validPalindrome(self, s: str) -> bool:
        n = len(s) #Record string length
        i = 0
        j = n - 1 
        delete_s = 1 #Delete the mark of one character
        answer_1 = answer_2 = False #It is discussed twice. When there is no match, delete the left character or right character
        while(i<=j):
            if(s[i]==s[j]):
                i += 1 
                j -= 1
                answer_1 = True 
            elif(delete_s):#Delete left character
                i += 1
                delete_s = 0
            else:
                answer_1 = False 
                break
        i = 0
        j = n - 1 
        delete_s = 1
        while(i<=j):
            if(s[i]==s[j]):
                i += 1 
                j -= 1
                answer_2 = True 
            elif(delete_s):#Delete right character
                j -= 1 
                delete_s = 0
            else:
                answer_2 = False
                break
        return answer_1 or answer_2
#188 ms	15.2 MB
#3_2

class Solution:
    def validPalindrome(self, s: str) -> bool:
        if s==s[::-1]:#Whether the front and back are equal
            return True
        l,r=0,len(s)-1#Define left and right pointers
        while l<r:
            if s[l]==s[r]:
                l+=1
                r-=1
            else:#In case of inequality, delete about one character slice for the unequal part
                a=s[l+1:r+1]
                b=s[l:r]

                return a==a[::-1] or b==b[::-1]#Judge whether one of them is the same
#52 ms	15.4 MB
#This topic falls into a circle. The code of the boss who copied on leetcode is linked below

2.4 name of Excel table column

Give you an integer columnNumber and return its corresponding column name in the Excel table.

For example:

A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
...

Example 1:
Input: columnNumber = 1
Output: "A"

Example 2:
Input: columnNumber = 28
Output: "AB"

Example 3:
Input: columnNumber = 701
Output: "ZY"

Example 4:
Input: columnNumber = 2147483647
Output: "FXSHRXW"

Tips:
1 <= columnNumber <= 231 - 1

#4_1
class Solution:
    def convertToTitle(self, columnNumber: int) -> str:
        res = "" 
        #Because there are 26 letters, but the remainder of 0 and 26 to 26 is 0, so borrow one from Shang to exclude the factor of 0
        while(columnNumber>0):
            columnNumber, y = divmod(columnNumber, 26) #Remainder array pair 26
            if y == 0: #If the remainder is 0, because excluding the factor of 0, we number it from 1-26.
                columnNumber -= 1#Borrow one from business
                y = 26#The remainder is 26
            res = chr(y + 64) + res#String addition construction, chr corresponds to converting ASCII 2 code into characters. On the contrary, ord (A) is 65
        return res
#52 ms	15.4 MB
#4_ Compared with the normal 26 base system of 0 ~ 25, 2 essentially adds 1 to each bit. Suppose A == 0, B == 1, then AB = 26 * 0 + 1 * 1, and now AB = 26 * (0 + 1) + 1 * (1 + 1), so as long as 1 is subtracted when processing each bit, it can be processed according to the normal 26 base
class Solution:
    def convertToTitle(self, columnNumber: int) -> str:
        res = ""
        while(columnNumber>0):
            columnNumber -= 1
            columnNumber, y = divmod(columnNumber, 26) 
            res = chr(y + 65) + res
        return res
#24 ms	14.8 MB
#4_ 3. The idea is the same as 2
class Solution:
    def convertToTitle(self, n: int) -> str:
        return "" if n == 0 else self.convertToTitle((n - 1) // 26) + chr((n - 1) % 26 + 65)
#36 ms	15 MB

Author: powcai
Link: https://leetcode-cn.com/problems/excel-sheet-column-title/solution/shi-jin-zhi-zhuan-26jin-zhi-by-powcai/
Source: LeetCode
The copyright belongs to the author. For commercial reprint, please contact the author for authorization. For non-commercial reprint, please indicate the source.

2.5 string decoding

Given an encoded string, returns its decoded string.
The coding rule is: k[encoded_string], indicating the encoded inside the square brackets_ String is repeated exactly k times. Note that K is guaranteed to be a positive integer.
You can think that the input string is always valid; There are no extra spaces in the input string, and the square brackets always meet the format requirements.
In addition, you can think that the original data does not contain numbers, and all numbers only represent the number of repetitions k, for example, there will be no input like 3a or 2 [4].

Example 1:
Input: s = "3[a]2[bc]"
Output: "aaabcbc"

Example 2:
Input: s = "3[a2[c]]"
Output: "accac"

Example 3:
Input: s = "2[abc]3[cd]ef"
Output: "abcabccdef"

Example 4:
Input: s = "abc3[cd]xyz"
Output: "abccdcdxyz"

Tips:
1 <= s.length <= 30
s consists of lowercase English letters, numbers and square brackets' [] '
s guarantee is a valid input.
The value range of all integers in s is [1, 300]

#5 regularization
class Solution:
    def decodeString(self, s: str) -> str:
        def encode(t: str) -> str:
            i = t.find('[')
            return int(t[:i]) * t[i+1:-1]

        regex = re.compile(r'\d+\[\w*\]')
        mo = regex.search(s)
        while mo:
            s = s.replace(mo.group(), encode(mo.group()))
            mo = regex.search(s)
        return s     
#28 ms	15.1 MB
#5_ 2 write with stack
class Solution:
    def decodeString(self, s: str) -> str:
        # Num save multiple
        nums = []
        stack = []
        # temp saves the string between [and]
        temp = []
        num = ''
        for i in s:
            # When numeric characters are encountered, they are combined and converted into multiples, such as: '66'
            if i.isdigit():
                num  += i
                continue
            # Through judgment, convert the numeric string in num into int and save it in num. only when the length of num is greater than 0 and i is not a number, can the number be saved
            if not i.isdigit() and len(num)>0:
                nums.append(int(num))
                num = ''
            # When encountering the closing bracket], start to exit the stack until encountering [stop]
            if i == ']':
                # Take the characters in the stack out of the stack until [stop] is encountered
                m = stack.pop()
                while m != '[':
                    temp.append(m)
                    m = stack.pop()
                # The left side of [must be a number, that is [..., s_num, '['], so stack Pop () is a multiple
                s_num = nums.pop()  
                # Partially doubled string
                # The direction of the character out of the stack is opposite to the direction of the original character, so pay attention to reverse back
                s_str = ''.join(temp[::-1])
                # Push the doubled string into the stack
                # s_num is a multiple
                while s_num: 
                    for j in s_str:
                        stack.append(j)
                    s_num -= 1
                temp = []
            else:
                stack.append(i)
            
        return ''.join(stack)
#36 ms	15.2 MB

Topics: Python Algorithm data structure leetcode