本文轉(zhuǎn)載自
作業(yè)部落的chanvee.
Merge Two Sorted Lists
這個(gè)題的意思是將兩個(gè)排序的鏈表合并為一個(gè),鏈表的操作,比較簡(jiǎn)單,代碼如下:
# 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
將羅馬數(shù)字轉(zhuǎn)化為整數(shù),只需要弄清楚羅馬數(shù)字的規(guī)則即可,規(guī)則如下:
- 相同的數(shù)字連寫(xiě),所表示的數(shù)等于這些數(shù)字相加得到的數(shù),如:Ⅲ = 3;
- 小的數(shù)字在大的數(shù)字的右邊,所表示的數(shù)等于這些數(shù)字相加得到的數(shù), 如:Ⅷ = 8;Ⅻ = 12;
- 小的數(shù)字,(限于Ⅰ、X 和C)在大的數(shù)字的左邊,所表示的數(shù)等于大數(shù)減小數(shù)得到的數(shù),如:Ⅳ= 4;Ⅸ= 9;
- 正常使用時(shí),連寫(xiě)的數(shù)字重復(fù)不得超過(guò)三次。(表盤(pán)上的四點(diǎn)鐘“IIII”例外)
- 在一個(gè)數(shù)的上面畫(huà)一條橫線(xiàn),表示這個(gè)數(shù)擴(kuò)大1000倍
這里第5條沒(méi)有用,因?yàn)檩斎氩粫?huì)出現(xiàn)這種情況,那么只需按著這個(gè)編碼規(guī)則即可,代碼如下:
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
這個(gè)題與上個(gè)題目相反,將整數(shù)轉(zhuǎn)化為羅馬數(shù)字。我的方法有點(diǎn)無(wú)恥,先建了3各表:1-9, 10:10:20, 100:100:900,這樣每次就只需要除完之后就可以從表里面提取,不用再去寫(xiě)一遍規(guī)則。代碼如下:
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
這個(gè)題的意思是比較兩個(gè)版本號(hào)的大小,方法簡(jiǎn)單,用split將字符串分割,然后依次比較大小即可。注意的特例是01 = 1,和1.0 = 1這兩類(lèi)例子,我們可以先把他們不起成為等長(zhǎng)。代碼如下:
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
判斷一個(gè)整數(shù)是不是回文,并且不能利用額外的空間,方法就是每次判斷最高位與最低位是否相同即可。代碼如下:
class Solution:
# @return a boolean
def isPalindrome(self, x):
mode, result= 1, True
while x//mode >= 10: ## 相當(dāng)于算出有多少位
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
這個(gè)題有點(diǎn)不好理解,反正我是看了網(wǎng)上的意思才懂了,意思是比如從1開(kāi)始,因?yàn)橹挥?個(gè)1,所以第二個(gè)數(shù)就是11(表示1個(gè)1),第二個(gè)數(shù)有2個(gè)1,所以第三個(gè)數(shù)為21(表示2個(gè)1),第三個(gè)數(shù)有1個(gè)2,1個(gè)1,所以第四個(gè)數(shù)是(1211)以此類(lèi)推,懂了意思就好做了。代碼如下:
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
判斷給定的數(shù)獨(dú)二維數(shù)組是否合法,我們只要弄清楚數(shù)獨(dú)的規(guī)則就行:
- 每一行只包含1-9,既每一行沒(méi)有重復(fù)的數(shù)字
- 每一列只包含1-9,即每一列沒(méi)有重復(fù)的數(shù)字
- 每個(gè)小九宮格里面只包含1-9....
接下來(lái)就簡(jiǎn)單了,遍歷他的所有行和列以及九宮格,看是否已經(jīng)存在相同的數(shù)字,如果存在則返回False,否則返回True。代碼如下:
class Solution:
# @param board, a 9x9 2D array
# @return a boolean
def isValidSudoku(self, board):
for i in range(9): # 行和列是否符合數(shù)獨(dú)
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): # 判斷九宮格是否有相同的數(shù)字
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): # 判斷列表中是否有相同的數(shù)字
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
從鏈表中移除倒數(shù)第N個(gè)數(shù)。思想很簡(jiǎn)單我就不再贅述了,有一個(gè)問(wèn)題是要想知道倒數(shù),就要知道鏈表中總共有多少個(gè)元素,這里我是先遍歷一遍得到長(zhǎng)度,不知道有沒(méi)有其他更好的辦法。代碼如下:
# 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
給定一個(gè)數(shù)字,將其轉(zhuǎn)換為Excel的title,其實(shí)就相當(dāng)于把一個(gè)數(shù)轉(zhuǎn)化為26進(jìn)制的數(shù)。代碼如下:
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
按照題目給的意思進(jìn)行字符串的映射,排列的形狀就是由以前的一行變?yōu)轭?lèi)似于多個(gè)倒著的N這種形狀的轉(zhuǎn)換。它的轉(zhuǎn)換規(guī)則如下:
- 如果是第一行或者最后一行,那么從第一個(gè)數(shù)開(kāi)始到下一個(gè)數(shù)每次相差
(2 * nRows - 2) - 對(duì)于其他行,這一行的數(shù)字的排列是奇數(shù)列和偶數(shù)列交替的,當(dāng)然列號(hào)不一定是連續(xù)的,但是他們的列號(hào)肯定是奇偶交替的
- 對(duì)于奇數(shù)列,兩個(gè)
相鄰的之間相差2 * (nRows - 1 - i)這么多個(gè)數(shù) - 對(duì)于偶數(shù)列,兩個(gè)
相鄰的之間相差2 * (nRows - i)這么多個(gè)數(shù)
根據(jù)上面的規(guī)則我們就可以對(duì)其進(jìn)行轉(zhuǎn)化了,代碼如下:
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: # 如果是奇數(shù)列
j += 2 * (nRows - 1 - i)
k = 1
else: # 如果是偶數(shù)列
j += 2 * i
k = 0
# 不能超過(guò)字符串的長(zhǎng)度
if j < len(s):
result += s[j]
i += 1
return(result)