LeetCode 题解3 (Python)

本文转载自作业部落chanvee.

Merge Two Sorted Lists


这个题的意思是将两个排序的链表合并为一个,链表的操作,比较简单,代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # @param two ListNodes
    # @return a ListNode
    def mergeTwoLists(self, l1, l2):
        result = ListNode(0)
        cur = result
        while l1 or l2:
            tmp = ListNode(0)
            if l1 and not l2:
                tmp = l1
                l1 = l1.next
            elif l2 and not l1:
                tmp = l2
                l2 = l2.next
            else:
                if l1.val < l2.val:
                    tmp = l1
                    l1 = l1.next
                else:
                    tmp = l2
                    l2 = l2.next
            cur.next, cur = tmp, tmp
        return(result.next)

Roman to Integer


将罗马数字转化为整数,只需要弄清楚罗马数字的规则即可,规则如下:

  1. 相同的数字连写,所表示的数等于这些数字相加得到的数,如:Ⅲ = 3;
  2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数, 如:Ⅷ = 8;Ⅻ = 12;
  3. 小的数字,(限于Ⅰ、X 和C)在大的数字的左边,所表示的数等于大数减小数得到的数,如:Ⅳ= 4;Ⅸ= 9;
  4. 正常使用时,连写的数字重复不得超过三次。(表盘上的四点钟“IIII”例外)
  5. 在一个数的上面画一条横线,表示这个数扩大1000倍
    这里第5条没有用,因为输入不会出现这种情况,那么只需按着这个编码规则即可,代码如下:
class Solution:
    # @return an integer
    def romanToInt(self, s):
        result = 0
        for i in range(len(s)):
            if s[i] == 'M':
                result += 1000
            elif s[i] == 'D':
                result += 500
            elif s[i] == 'C':
                if i + 1 < len(s) and (s[i+1] == 'M' or s[i+1] == 'D'):
                    result -= 100
                else:
                    result += 100
            elif s[i] == 'L':
                result += 50 
            elif s[i] == 'X':
                if i + 1 < len(s) and (s[i+1] == 'M' or s[i+1] == 'D' or s[i+1] == 'C' or s[i+1] == 'L'):
                    result -= 10
                else:
                    result += 10
            elif s[i] == 'V':
                result += 5
            else:
                if i + 1 < len(s) and (s[i+1] == 'M' or s[i+1] == 'D' or s[i+1] == 'C' or s[i+1] == 'L' or s[i+1] == 'X' or s[i+1] == 'V'):
                    result -= 1
                else:
                    result += 1
        return(result)  

Integer to Roman


这个题与上个题目相反,将整数转化为罗马数字。我的方法有点无耻,先建了3各表:1-9, 10:10:20, 100:100:900,这样每次就只需要除完之后就可以从表里面提取,不用再去写一遍规则。代码如下:

class Solution:
    # @return a string
    def intToRoman(self, num):
        LesTen = ['I','II','III','IV','V','VI','VII','VIII','IX']
        LesHun = ['X','XX','XXX','XL','L','LX','LXX','LXXX','XC']
        LesThu = ['C','CC','CCC','CD','D','DC','DCC','DCCC','CM']
        result = []
        while num > 0:
            if num // 1000:
                result.append('M'*(num // 1000))
                num %= 1000
            elif num // 100:
                result.append(LesThu[num//100 - 1])
                num %= 100
            elif num // 10:
                result.append(LesHun[num//10 -1])
                num %= 10
            else:
                result.append(LesTen[num -1])
                num //= 10
        result = ''.join(result)
        return(result)

Compare Version Numbers


这个题的意思是比较两个版本号的大小,方法简单,用split将字符串分割,然后依次比较大小即可。注意的特例是01 = 1,和1.0 = 1这两类例子,我们可以先把他们不起成为等长。代码如下:

class Solution:
    # @param a, a string
    # @param b, a string
    # @return a boolean
    def compareVersion(self, version1, version2):
        if version1 == version2:
            return(0)
        ver1 = version1.split('.')
        ver2 = version2.split('.')
        flag = 1
        for i in range(abs(len(ver1)-len(ver2))):
            if len(ver1) <= len(ver2):
                ver1.append('0')
            else:
                ver2.append('0')
        for i in range(min(len(ver1), len(ver2))):
            if int(ver1[i]) > int(ver2[i]):
                flag = 0
                return(1)
            if int(ver1[i]) < int(ver2[i]):
                flag = 0
                return(-1)
        if flag:
            if len(ver1) == len(ver2):
                return(0)
            if len(ver1) < len(ver2):
                return(-1)
            if len(ver1) > len(ver2):
                return(1)

Palindrome Number


判断一个整数是不是回文,并且不能利用额外的空间,方法就是每次判断最高位与最低位是否相同即可。代码如下:

class Solution:
    # @return a boolean
    def isPalindrome(self, x):
        mode, result= 1, True
        while x//mode >= 10: ## 相当于算出有多少位
            mode *= 10
        while x:
            if x // mode != x % 10:
                result = False
                return(result)
            x -= mode*(x//mode) 
            x //= 10
            mode //= 100
        return(result)

Count and Say


这个题有点不好理解,反正我是看了网上的意思才懂了,意思是比如从1开始,因为只有1个1,所以第二个数就是11(表示1个1),第二个数有2个1,所以第三个数为21(表示2个1),第三个数有1个2,1个1,所以第四个数是(1211)以此类推,懂了意思就好做了。代码如下:

class Solution:
    # @return a string
    def countAndSay(self, n):
        if n == 1:
            return('1')
        if n == 2:
            return('11')
        result = []
        s = '11'
        for i in range(n-2):
            s = self.Trans(s)
        result = ''.join(s)
        return(result)
    def Trans(self, s):
        result = []
        tmp, count = s[0], 1
        for i in range(1,len(s)):
            if s[i] == s[i-1]:
                count += 1
                if i == len(s)-1:
                    result.append(str(count)+s[i-1])
            else:
                result.append(str(count)+s[i-1])
                tmp, count = s[i], 1
                if i == len(s)-1:
                    result.append(str(count)+s[i])
        result = ''.join(result)
        return(result)

Valid Sudoku


判断给定的数独二维数组是否合法,我们只要弄清楚数独的规则就行:

  1. 每一行只包含1-9,既每一行没有重复的数字
  2. 每一列只包含1-9,即每一列没有重复的数字
  3. 每个小九宫格里面只包含1-9....
    接下来就简单了,遍历他的所有行和列以及九宫格,看是否已经存在相同的数字,如果存在则返回False,否则返回True。代码如下:
class Solution:
    # @param board, a 9x9 2D array
    # @return a boolean
    def isValidSudoku(self, board):
        for i in range(9): # 行和列是否符合数独
            tmp = []
            tmp1 = []
            for j  in range(9):
                tmp.append(board[i][j])
                tmp1.append(board[j][i])
            if self.isnodifferent(tmp) == False or self.isnodifferent(tmp1) == False:
                return(False)
        for i in range(0,9,3): # 判断九宫格是否有相同的数字
            for j in range(0,9,3):
                tmp = []
                tmp.append(board[i][j])
                tmp.append(board[i][j+1])
                tmp.append(board[i][j+2])
                tmp.append(board[i+1][j])
                tmp.append(board[i+1][j+1])
                tmp.append(board[i+1][j+2])
                tmp.append(board[i+2][j])
                tmp.append(board[i+2][j+1])
                tmp.append(board[i+2][j+2])
                if not self.isnodifferent(tmp): 
                    return(False)
        return(True)
    def isnodifferent(self, s): # 判断列表中是否有相同的数字
        while '.' in  s:
            s.remove('.')
        if s == []:
            return(True)
        flag = 0
        tmp = []
        tmp.append(s[0])
        for i in range(1, len(s)):
            if s[i] in tmp:
                flag = 1
                break
            tmp.append(s[i])
        if flag:
            return(False)
        else:
            return(True)

Remove Nth Node From End of List


从链表中移除倒数第N个数。思想很简单我就不再赘述了,有一个问题是要想知道倒数,就要知道链表中总共有多少个元素,这里我是先遍历一遍得到长度,不知道有没有其他更好的办法。代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # @return a ListNode
    def removeNthFromEnd(self, head, n):
        tmp =  head
        L = 0 
        while tmp:
            L += 1
            tmp = tmp.next
        if n == L:
            return(head.next)
        tmp = head
        for i in range(L):
            if i == L - n -1:
                tmp.next = tmp.next.next
                break
            tmp = tmp.next
        return(head)

Excel Sheet Column Title


给定一个数字,将其转换为Excel的title,其实就相当于把一个数转化为26进制的数。代码如下:

class Solution:
    # @return a string
    def convertToTitle(self, num):
        dic = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        result = ''
        while num:
            result = result + dic[(num-1)%26]
            num = (num - 1) // 26
        return(result[::-1])

ZigZag Conversion


按照题目给的意思进行字符串的映射,排列的形状就是由以前的一行变为类似于多个倒着的N这种形状的转换。它的转换规则如下:

  1. 如果是第一行或者最后一行,那么从第一个数开始到下一个数每次相差(2 * nRows - 2)
  2. 对于其他行,这一行的数字的排列是奇数列和偶数列交替的,当然列号不一定是连续的,但是他们的列号肯定是奇偶交替的
  3. 对于奇数列,两个相邻的之间相差2 * (nRows - 1 - i)这么多个数
  4. 对于偶数列,两个相邻的之间相差2 * (nRows - i)这么多个数
    根据上面的规则我们就可以对其进行转化了,代码如下:
class Solution:
    # @return a string
    def convert(self, s, nRows):
        result = ''
        if s == '' or nRows <= 1:
            return(s)
        i = 0
        while(i < len(s) and i < nRows):
            j = i
            result += s[j]
            k = 0
            while j < len(s):
                # 如果是第一行或最后一行 
                if i == 0 or i == nRows - 1:
                    j += 2 * nRows - 2;   
                else:
                    if k == 0: # 如果是奇数列
                        j += 2 * (nRows - 1 - i)
                        k = 1
                    else: # 如果是偶数列
                        j += 2 * i 
                        k = 0
                # 不能超过字符串的长度
                if j < len(s):
                    result += s[j]  
            i += 1
        return(result)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容