LeetCode-String

来源:互联网 发布:手游抢激活码软件 编辑:程序博客网 时间:2024/06/02 01:06

LeetCode-String

13.Roman to Integer

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.
罗马数字采用七个罗马字母作数字:
I(1)、X(10)、C(100)、M(1000)、V(5)、L(50)、D(500)。

记数的方法:

  1. 相同的数字连写,所表示的数等于这些数字相加得到的数,如 III=3;

  2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 VIII=8、XIII=12;

  3. 小的数字(限于 I、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 IV=4、IX=9;

  4. 在一个数的上面画一条横线,表示这个数增值 1,000 倍。

根据上面说的计数方法的前三条。对于输入的罗马数字字符串,从后向前扫描,遇到前面数大于等于后面的最大数的时候,相加;遇到前面数小于后面的最大数的时候,相减。

    class Solution(object):        def romanToInt(self, s):            """            :type s: str            :rtype: int            """            digits = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}            sum = 0            maxDigit = 1            for i in xrange(len(s)-1, -1, -1):                if digits[s[i]] >= maxDigit:                    maxDigit = digits[s[i]]                    sum += digits[s[i]]                else:                    sum -= digits[s[i]]            return sum

20. Valid Parentheses

括号匹配算法

class Solution(object):    def isValid(self, s):        """        :type s: str        :rtype: bool        """        stack = []        if s=='':            return True        if '[' not in s and '(' not in s and '{' not in s:            return False        for i in range(0,len(s)):            if s[i] == ')' or s[i] == '}' or s[i] == ']':                if stack ==[]:                    return False            if s[i]== '(' or s[i]== '[' or s[i]== '{' :                stack.append(s[i])            if s[i] == ')' :                if stack[-1] == '(':                    stack.pop()                else:                    return False            if s[i] == ']' :                if stack[-1] == '[':                    stack.pop()                else:                    return False            if s[i] == '}' :                if stack[-1] == '{':                    stack.pop()                else:                    return False        if stack==[]:            return True        else:            return Falseclass Solution(object):    def isValid(self, s):        """        :type s: str        :rtype: bool        """        dict = {'(':')', '[':']', '{':'}'}        arr = []        for char in s:            if char in dict:                arr.append(char)            elif len(arr) > 0 and dict[arr[-1]] == char:                arr.pop()            else:                return False        if len(arr) == 0:            return True        else:            return False

28. Implement strStr()

Implement strStr().

Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.

class Solution(object):    def strStr(self, haystack, needle):        """        :type haystack: str        :type needle: str        :rtype: int        """        if len(needle) > len(haystack):            return -1        if len(needle) == len(haystack):            return 0 if needle == haystack else -1        try:            return haystack.index(needle)        except ValueError:            return -1class Solution(object):    def strStr(self, haystack, needle):        """        :type haystack: str        :type needle: str        :rtype: int        """        return haystack.find(needle)

38. Count and Say

class Solution(object):    def helper(self, n, s):        if not n:            return s        pre = s[0]        res = ''        count = 1        for i in range(1, len(s)):            if s[i] == pre:                count += 1            else:                res += str(count) + pre                count = 1                pre = s[i]        res += str(count) + pre        return self.helper(n - 1, res)    def countAndSay(self, n):        """        :type n: int        :rtype: str        """        s = '1'        if n == 1:            return s        return self.helper(n - 1, s)

58.length of last word

“hello word” 返回 5
“a ” 返回1
class Solution(object):
def lengthOfLastWord(self, s):
“””
:type s: str
:rtype: int
“””
for i in range(len(s)-1,-1,-1):
if s[i]==’ ‘:
s = s[0:i]
else:
break
if s == None:
return 0
s = s.split(’ ‘)
print(s[-1])
return len(s[-1])
class Solution(object):
def lengthOfLastWord(self, s):
“””
:type s: str
:rtype: int
“””
s=s.strip()
if len(s)==0:
return 0
for i in xrange(len(s)-1,0,-1):
if s[i]==’ ‘:
return len(s)-i-1
return len(s)

171.ExcelSheetColumnNumber

字母A-Z算作1-26,即26进制转十进制。如 ‘AB’ 表示28

我的思路是反转字符串,从个位起计算,方便理解

def titleToNumber(s):    """    :type s: str    :rtype: int    """    num = 0    exp = 1    s=s[::-1]    for i in range(0,len(s)):        num = num + (ord(s[i])-ord('A')+1)*exp        exp = exp*26    return num


网上的做法是:

class Solution(object):    def titleToNumber(self, s):        """        :type s: str        :rtype: int        """        ret = 0        for i,v in (enumerate(s)):            #print(ret,ret * 26,ord(v),ord('A'))            #print(ret*26,ord(v)-ord('A')+1)            #print("ret1",ret)            ret = ret * 26 + ord(v) - ord('A')+1            #print("ret2",ret)        return ret

205. Isomorphic Strings

先遍历一遍s和t,将s到t的字符映射存放在dict中,遍历过程中如果发现某个位置的映射与已经确定的映射冲突则可以直接返回false。但这个过程无法发现“不同的字符映射到相同的字符”这一情况,所以最后还要判断得到的映射关系是否有重复。

class Solution(object):    def isIsomorphic(self, s, t):        """        :type s: str        :type t: str        :rtype: bool        """        hashmap = {}        for i in xrange(len(s)):            if s[i] not in hashmap:                hashmap[s[i]] = t[i]            elif hashmap[s[i]] != t[i]:                return False        mapval = [hashmap[k] for k in hashmap]        return len(mapval) == len(set(mapval))

对于s和t,分别用一个数组记录每个字符在该字符串中上一次出现的位置。当同时遍历s和t时,如果发现它们在某一位置的字符上次出现的位置不同,则返回false。
class Solution(object):
def isIsomorphic(self, s, t):
“””
:type s: str
:type t: str
:rtype: bool
“””
pos1, pos2 = [-1]*256, [-1]*256
for i in xrange(len(s)):
if pos1[ord(s[i])] != pos2[ord(t[i])]:
return False
pos1[ord(s[i])] = pos2[ord(t[i])] = i
return True

290. Word Pattern

Given a pattern and a string str, find if str follows the same pattern.

Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str.

Examples:

pattern = “abba”, str = “dog cat cat dog” should return true.

pattern = “abba”, str = “dog cat cat fish” should return false.

class Solution(object):    def wordPattern(self, pattern, str):        """        :type pattern: str        :type str: str        :rtype: bool        """        s = str.split(' ')        word_dict = {}        if len(pattern)!= len(s):            return False        for i in range(0,len(pattern)):            if pattern[i] not in word_dict:                word_dict[pattern[i]] = s[i]            else:                if s[i]!= word_dict[pattern[i]]:                    return False        for k in word_dict.keys():            for j in word_dict.keys():                if word_dict[k]==word_dict[j]:                    if k!=j:                        return False        return True

网上判断V相同,K不相同的方法(映射一一对应,一个K对应一个V,不能一对多,或者多对一)

class Solution(object):    def wordPattern(self, pattern, str):        """        :type pattern: str        :type str: str        :rtype: bool        """        words = str.split()        if len(pattern) != len(words):            return False        dic = {}        for i in xrange(len(words)):            if pattern[i] in dic:                if words[i] != dic[pattern[i]]:                    return False            elif words[i] in dic.values():                return False            dic[pattern[i]] = words[i]        return True

242.ValidAnagram

判断一个字符串是否是另一个字符串重新排列的样子,也就是说这两个字符串元素及个数相同,使用dict存储元素及相应个数即可

def isAnagram(s, t):    """    :type s: str    :type t: str    :rtype: bool    """    s_dict={}    t_dict={}    for i in s :        if i not in s_dict:            s_dict[i] =1        else:            s_dict[i]+=1    for i in t :        if i not in t_dict:            t_dict[i] =1        else:            t_dict[i]+=1    if s_dict == t_dict:        return True    else:        return False

344.ReverseStr

反转字符串最简单的当然是return str[::-1]。这里给出其他四种方法

1.交换前后字母的位置

def string_reverse(string):      t = list(string)      l = len(t)      for i,j in zip(range(l-1, 0, -1), range(l//2)):          t[i], t[j] = t[j], t[i]      return "".join(t)  

2.递归的方式, 每次输出一个字符

def string_reverse(string):      if len(string) <= 1:          return string      return string_reverse3(string[1:]) + string[0]  

3.双端队列, 使用extendleft()函数

from collections import deque  def string_reverse4(string):      d = deque()      d.extendleft(string)      return ''.join(d)  

4.使用for循环, 从左至右输出;

def string_reverse5(string):       return ''.join(string[i] for i in range(len(string)-1, -1, -1))  

345. Reverse Vowels of a String

思路一

一遍扫描所有字符,记录所有元音字母和它们出现的位置到一个数组中;再扫描这个数组,将元音字母逆序填回原来的字符串相应位置。

class Solution(object):    def reverseVowels(self, s):        """        :type s: str        :rtype: str        """        res = list(s)        vowels = []        for i in xrange(len(res)):            if res[i] in ['a', 'o', 'e', 'i', 'u', 'A', 'O', 'E', 'I', 'U']:                vowels.append((i, res[i]))        for j in xrange(len(vowels)/2):            res[vowels[j][0]] = vowels[len(vowels)-j-1][1]            res[vowels[len(vowels)-j-1][0]] = vowels[j][1]        return ''.join(res)

思路二

思路一里面要顺序记录出现的元音字母和位置,但是在第二遍循环时只用考虑记录这些位置上的字母的变化。其实也可以只顺序记录所有的元音字母,第二遍循环重新遍历原始字符串,将遇到的元音字母替换成刚才记录的逆序排列。

class Solution(object):    def reverseVowels(self, s):        """        :type s: str        :rtype: str        """        vowels = re.findall('(?i)[aeiou]', s)        return re.sub('(?i)[aeiou]', lambda m: vowels.pop(), s)

思路三

维护两个指针分别从字符串头和尾扫描,每次交换两个指针扫到的元音字母,于是只需遍历一遍字符串就可以完成元音字母逆序。

class Solution(object):    def reverseVowels(self, s):        """        :type s: str        :rtype: str        """        vowels = {'a': True, 'o': True, 'e': True, 'i': True, 'u': True, 'A': True, 'O': True, 'E': True, 'I': True, 'U': True}        res = list(s)        pos = []        for i in xrange(len(res)):            if res[i] in vowels:                pos.append((i, res[i]))        for j in xrange(len(pos)/2):            res[pos[j][0]] = pos[len(pos)-j-1][1]            res[pos[len(pos)-j-1][0]] = pos[j][1]        return ''.join(res)

434. Number of Segments in a String

返回字符串中段的个数,一段就是非空格字符串

class Solution(object):    def countSegments(self, s):        """        :type s: str        :rtype: int        """        if s=='':            return 0        count = 0        for i in range(0,len(s)):            if i-1>=0:                if s[i]==' ' and s[i-1] !=' ':                    count+=1        if s[-1]!=' ':            count+=1        return countclass Solution(object):    def countSegments(self, s):        import re        s = s.strip()        if s == "":            return 0        else:            return len(re.split("\s+",s))class Solution(object):    def countSegments(self, s):        """        :type s: str        :rtype: int        """        return len(s.split())

438. Find All Anagrams in a String

返回p(p的任意顺序也可以)在s中的索引
class Solution(object):
def findAnagrams(self, s, p):
“””
:type s: str
:type p: str
:rtype: List[int]
“””
n, step = len(s), len(p)
sp = sorted(p)
pset = set(p)

        result = []        idx = 0        # idx to idx+step (idx+step <= n)        while idx < n - step + 1:            if s[idx] in pset:                if sp == sorted(s[idx:idx + step]):                    result.append(idx)                    while idx < (len(s) - step):                        # extend to last one so idx cannot be len(s) - step                        if s[idx] == s[idx + step]:                            idx += 1                            result.append(idx)                        else:                            if s[idx + step] not in pset:                                idx += step                            break            idx += 1        return result

541.ReverseStringII

长度为l,如果k>l,则全部反转,如果k

383. Ransom Note

判断后一个字符串是否包含前一个字符串的所有字符

class Solution(object):    def canConstruct(self, ransomNote, magazine):        """        :type ransomNote: str        :type magazine: str        :rtype: bool        """        for i in set(ransomNote):            if ransomNote.count(i) > magazine.count(i):                return False        return True

387. First Unique Character in a String

返回字符串中第一个单独的字母的索引

def firstUniqChar(s):    """    :type s: str    :rtype: int    """    str_dict = {}    a=''    for i in s:        if i not in str_dict:            str_dict[i] = 1        else:            str_dict[i]+=1    for i,k in enumerate(str_dict):        if str_dict[k]==1:            a=k            break    for j,key in enumerate(s):        if key==a:            return j    return -1class Solution(object):    def firstUniqChar(self, s):        """        :type s: str        :rtype: int        """        letters = {}        for c in s:            letters[c] = letters[c] + 1 if c in letters else 1        for i in xrange(len(s)):            if letters[s[i]] == 1:                return i        return -1class Solution(object):    def firstUniqChar(self, s):        """        :type s: str        :rtype: int        """        letters='abcdefghijklmnopqrstuvwxyz'        # index=[s.index(l) for l in letters if s.count(l) == 1]        # return min(index) if len(index) > 0 else -1        index = [s.index(l) for l in letters if s.count(l) == 1]        if len(index) > 0:            return min(index)        else:            return -1

389.FindtheDifference

找出t比s多的那个字母

def findTheDifference(s, t):    """    :type s: str    :type t: str    :rtype: str    """    s_sum = 0    t_sum = 0    for i in range(0,len(s)):        s_sum += ord(s[i])    for j in range(0,len(t)):        t_sum += ord(t[j])    return chr(t_sum-s_sum)def findTheDifference(self, s, t):    """    :type s: str    :type t: str    :rtype: str    """    dictionary={}    for ch in t:        if ch in dictionary:            dictionary[ch]=dictionary[ch]+1        else:            dictionary[ch]=1    for ch in s:        dictionary[ch]=dictionary[ch]-1    for i in dictionary.keys():        if dictionary[i]!=0:            return i

409.LongestPalindrome

找出字符串中最长回文串的长度,将每个字符及个数加入dict,遍历dict,如果 个数能整除2,说明能对称,加上个数即可。不能整除2,则向下整除2、再乘以2,加上即可。如果最后长度小于len(s),说明存在一个字母个数为奇数,则再加1,把这个数放在最中间即可

def longestPalindrome(s):    """    :type s: str    :rtype: int    """    length = 0    s_dict={}    for i in s:        if i not in s_dict:            s_dict[i] = 1        else:            s_dict[i] +=1    print(s_dict)    for i in s_dict:        if s_dict[i]%2==0:            length += s_dict[i]        else:            length+= (s_dict[i]//2)*2    if length!=len(s):        return length+1    else:        return length

方便的做法是利用count():

    class Solution(object):        def longestPalindrome(self, s):            """            :type s: str            :rtype: int            """            result = 0            mark = set(s)            for ch in mark:                result += s.count(ch)//2*2            if len(s) != result:                result += 1            return result

459. Repeated Substring Pattern

判断字符串是不是由重复子串构成

class Solution(object):    def repeatedSubstringPattern(self, str):        """        :type str: str        :rtype: bool        """        size = len(str)        for x in range(1, size / 2 + 1):            if size % x:                continue            if str[:x] * (size / x) == str:                return True        return Falseclass Solution(object):    def repeatedSubstringPattern(self, s):        """        :type s: str        :rtype: bool        """        new_s = s + s        i = new_s.find(s, 1)        if i < len(s):            return True        return False    def repeatedSubstringPattern(self, s):        """        :type s: str        :rtype: bool        """        return s in (s+s)[1:-1]

500.KeyboardRow

判断给出字符串是否属于键盘的某一行

class Solution(object):    def findWords(self, words):        """        :type words: List[str]        :rtype: List[str]        """        a = set('QWERTYUIOPqwertyuiop')        b = set('ASDFGHJKLasdfghjkl')        c = set('ZXCVBNMzxcvbnm')        l = []        for i in words:            temp = set(i)            if temp.issubset(a) or temp.issubset(b) or temp.issubset(c):                l.append(i)        return l

520.DetectCapital

我的蠢办法:

    def detectCapitalUse(word):        """        :type word: str        :rtype: bool        """        allUpper = True        allLower = True        for i in word:            if ord(i)>90 or ord(i)<65:                allUpper = False        if allUpper == True:            return True        for i in word:            if ord(i)>122 or ord(i)<97:                allLower = False        if allLower == True:            return True        flag = True        if ord(word[0])>=65 and ord(word[0])<=90:            for i in word[1:]:                if ord(i)> 122 or ord(i) < 97:                    flag = False            if flag ==True:                return True        return Falseclass Solution(object):    def detectCapitalUse(self, word):        """        :type word: str        :rtype: bool        """        return  word.isupper() or word.istitle() or word.islower()    def detectCapitalUse(self, word):        """        :type word: str        :rtype: bool        """        if word.isupper() or word.islower():            return True        else:            c = word[0]            e = word[1:]            if e.islower() and c.isupper():                return True        return False

521. Longest Uncommon Subsequence I

class Solution(object):def findLUSlength(self, a, b):    """    :type a: str    :type b: str    :rtype: int    """    return a != b and max(len(a), len(b)) or -1    #若两字符串不相等,选择较长的字符串返回长度即可。    # 否则返回-1。(若两字符串相等,则任意字符串的子串均为另一个的子串)

551.StudentAttendanceRecordI

字符串只有P,L,A三种字符,A不能大于1个,L不能连续两个以上

def checkRecord(s):    """    :type s: str    :rtype: bool    """    a =set('PLA')    for i in s:        if i not in a:            return False    if s.count('A')>1:        return False    for i in range(0,len(s)):        if s[i]=='L' and (i+2)<len(s):            if s[i+1]=='L' and s[i+2]=='L':                return False    return True

415.AddString

给定两个由数字组成的字符串,对这两个字符串相加

注意:

num1和num2的长度< 5100

num1和num2只包含数字0-9

num1和num2不包含前导0

你不能使用内置的BigInteger库,也不能直接把输入转换为整数。

基本思想是从后向前遍历字符串,依次相加。carry表示有进位为1,无进位为0,把相加的个位数存入数组,最后倒序形成字符串

class Solution(object):    def addStrings(self, num1, num2):        """        :type num1: str        :type num2: str        :rtype: str        """        result = []        carry = 0        idx1, idx2 = len(num1), len(num2)        while idx1 or idx2 or carry:            digit = carry            if idx1:                idx1 -= 1                digit += int(num1[idx1])            if idx2:                idx2 -= 1                digit += int(num2[idx2])            carry = digit > 9            result.append(str(digit % 10))        return ''.join(result[::-1])

657.Judge Route Circle

Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place.

The move sequence is represented by a string. And each move is represent by a character. The valid robot moves are R (Right), L (Left), U (Up) and D (down). The output should be true or false representing whether the robot makes a circle.

Example 1:

Input: “UD”
Output: true

Example 2:

Input: “LL”
Output: false

class Solution(object):    def judgeCircle(self, moves):        """        :type moves: str        :rtype: bool        """        hor = 0        ver = 0        for i in moves:            if i == 'U':                ver = ver +1            if i=='D':                ver = ver-1            if i=='L':                hor = hor+1            if i=='R':                hor = hor -1        if hor ==0 and ver ==0:            return True        else:            return Falseclass Solution(object):    def judgeCircle(self, moves):        """        :type moves: str        :rtype: bool        """        return moves.count('L') - moves.count('R') == 0 and moves.count('U') - moves.count('D') == 0

680. Valid Palindrome II

删去一个字母后是否还是回文串

class Solution(object):    def validPalindrome(self, s):        rev = s[::-1]        if s == rev:            return True        l = len(s)        for i in xrange(l):            if s[i] != rev[i]:                return s[i:l-i-1] == rev[i+1:l-i] or rev[i:l-i-1] == s[i+1:l-i]        return False

734.Sentence Similarity

判断两个句子是否相似。

def areSentencesSimilar(words1, words2, pairs):    """    :type words1: List[str]    :type words2: List[str]    :type pairs: List[List[str]]    :rtype: bool    """    if len(words1)!=len(words2):        return False    similars = collections.defaultdict(set)    for w1, w2 in pairs:        similars[w1].add(w2)        similars[w2].add(w1)    for w1, w2 in zip(words1, words2):        if w1 != w2 and w2 not in similars[w1]:            return False    return True