[Python] [LeetCode] [競技プログラミング]
1. Two Sum
整数の配列が与えられたとき、特定の目標に足し算されるような2つの数値のインデックスを返します。
各入力が正確に1つの解を持つと仮定して、同じ要素を2回使用することはできません。
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
h = {}
for i, num in enumerate(nums):
n = target - num
if n not in h:
h[num] = i
else:
return [h[n], i]
2. Add Two Numbers
2つの非負の整数を表す空ではない2つのリンクリストが与えられます。
数字は逆順に格納され、それぞれのノードには1桁の数字が含まれています。2つの数値を足し算して、リンクリストとして返します。
2つの数値には,0を除いて、先頭の0が含まれていないと仮定してもよい。
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
quotient = 0
count = 0
while l1 or l2 or quotient:
count += 1
val1 = (l1.val if l1 else 0)
val2 = (l2.val if l2 else 0)
quotient, remainder = divmod(val1+val2 + quotient, 10)
if count == 1:
first = ListNode(remainder)
end = first
else:
end.next = ListNode(remainder)
end = end.next
l1 = (l1.next if l1 else None)
l2 = (l2.next if l2 else None)
return first
3. Longest Substring Without Repeating Characters
文字列が与えられたとき、文字を繰り返さずに最長の部分文字列の長さを求めなさい。
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
class Solution:
def lengthOfLongestSubstring(self, s):
alphabet = {}
start_id = 0
max_length = 0
for id, char in enumerate(s):
if char in alphabet and alphabet[char] >= start_id:
start_id = alphabet[char] + 1
alphabet[char] = id
length = id - start_id + 1
if max_length < length:
max_length = length
return max_length
4. Median of Two Sorted Arrays
サイズmとnの2つのソートされた配列nums1とnums2がある。
2つの並べ替え配列の中央値を求めよ.全体の実行時間の複雑さは,O(log (m+n))でなければなりません。
nums1 と nums2 はどちらも空ではないと仮定してもよい。
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
class Solution:
def findMedianSortedArrays(self,nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
sorted_joined = sorted(nums1 + nums2)
if len(sorted_joined) % 2 == 0:
index = int(len(sorted_joined) / 2)
return (sorted_joined[index] + sorted_joined[index-1])/2.0
else:
index = (int(len(sorted_joined)/2))
return sorted_joined[index]
5. Longest Palindromic Substring
文字列 s が与えられたとき、s の中で最も長い回文の部分文字列を見つけなさい。
s の最大長は1000であると仮定してもよい。
Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Input: "cbbd"
Output: "bb"
class Solution:
# Manacher's algorithm
def longestPalindrome(self, s):
T = '#'.join('^{}$'.format(s))
n = len(T)
P = [0] * n
C = R = 0
for i in range (1, n-1):
P[i] = (R > i) and min(R - i, P[2*C - i])
while T[i + 1 + P[i]] == T[i - 1 - P[i]]:
P[i] += 1
if i + P[i] > R:
C, R = i, i + P[i]
maxLen, centerIndex = max((n, i) for i, n in enumerate(P))
return s[(centerIndex - maxLen)//2: (centerIndex + maxLen)//2]
参考文献
GeeksforGeeks:Manacher’s Algorithm
6. ZigZag Conversion
"PAYPALISHIRING"という文字列は、このように所定の行数にジグザグパターンで書かれています。
(読みやすくするために、このパターンを固定フォントで表示するとよいでしょう)
P A H N
A P L S I I G
Y I R
そして、一行ずつ読んでいくと "PAHNAPLSIIGYIR"。
文字列を受け取り、行数を指定してこの変換を行うコードを書いてください。
string convert(string s, int numRows);
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
P A H N
A P L S I I G
Y I R
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
class Solution:
def convert(self, s, numRows):
if numRows == 1:
return s
step = 1
pos = 1
lines = {}
for c in s:
if pos not in lines:
lines[pos] = c
else:
lines[pos]+=c
pos+=step
if pos==1 or pos==numRows:
step*=-1
sol = ""
for i in range(1, numRows+1):
try:
sol+=lines[i]
except:
return sol
return sol
7. Reverse Integer
32ビット符号付き整数が与えられたとき、整数の逆数を計算します。
Input: 123
Output: 321
Input: -123
Output: -321
Input: 120
Output: 21
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
if x > 0:
a = int(str(x)[::-1])
if x <=0:
a = -1 * int(str(x*-1)[::-1])
mina = -2**31
maxa = 2**31 - 1
if mina <= a <= maxa:
return a
else:
return 0
8. String to Integer (atoi)
文字列を整数に変換する atoi を実装する。
この関数はまず、最初の空白以外の文字が見つかるまで必要なだけの空白文字を破棄します。そして、この文字から始めて、オプションの最初のプラスまたはマイナス記号の後に可能な限り多くの数字を続けて取り、それらを数値として解釈します。
文字列には、積分数を形成する文字の後に追加の文字を含めることができますが、これらの文字は無視され、この関数の動作には何の影響もありません。
strの最初の空白以外の文字列が有効な整数ではない場合、あるいは、 strが空であるか、空白文字しか含まれていないためにそのような文字列が存在しない場合、変換は実行されません。
有効な変換ができなかった場合、0の値が返されます。
注意
スペース文字 '' ' のみが空白文字とみなされます。
32ビット符号付き整数の範囲内の整数しか格納できない環境を扱っていると仮定します。
[−2^(31), 2^(31) − 1]. 数値が表現可能な範囲外の場合、INT_MAX (2^(31) - 1) または INT_MIN (-2^(31)) が返されます。
Input: "42"
Output: 42
Input: " -42"
Output: -42
Explanation: The first non-whitespace character is '-', which is the minus sign.
Then take as many numerical digits as possible, which gets 42.
Input: "4193 with words"
Output: 4193
Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.
Input: "words and 987"
Output: 0
Explanation: The first non-whitespace character is 'w', which is not a numerical
digit or a +/- sign. Therefore no valid conversion could be performed.
Input: "-91283472332"
Output: -2147483648
Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer.
Thefore INT_MIN (−231) is returned.
class Solution(object):
def is_num(self, str):
try:
float(str)
except ValueError:
return False
else:
return True
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
word = str.strip().split() # extraction
#==================================================
if not word:
return 0 # case: ""
#==================================================
else:
word = word[0]
char = list(word)
sign = 1
#===============================================
if char[0] == "-": # minus sign
if len(char) == 1: # case: "-"
return 0 # [RETURN]
else:
#char = char[1:] # without sign
end_id = 2 # end id
sign = -1 # sign
#===============================================
elif char[0] == "+": # plus sign
if len(char) == 1: # case: "+"
return 0 # [RETURN]
else:
#char = char[1:] # without sign
end_id = 2 # end id
#===============================================
else:
end_id = 1 # end id
#===============================================
for id in range(end_id, len(word)+1):
if not self.is_num(word[0:id]):
if id == end_id:
return 0
break
num = word[0:id]
#===============================================
a = int(float(num))
#===============================================
mina = -2**31
maxa = 2**31 - 1
#===============================================
if mina <= a <= maxa:
return a
elif mina > a:
return mina
else:
return maxa
9. Palindrome Number
整数が回文かどうかを判定します。
整数は、後ろ向きと前向きが同じ読み方をすると回文になります。
Input: 121
Output: true
Input: -121
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Input: 10
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
class Solution(object):
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
return str(x) == str(x)[::-1]
10. Regular Expression Matching
入力文字列 (s) とパターン (p) が与えられた場合、'.' と '*' をサポートした正規表現マッチングを実装します。
'.':任意の1文字にマッチします。
'*':前の要素のうち、0個以上の要素にマッチします。
マッチングは入力文字列全体をカバーしなければなりません(部分的なものではありません)。
注意
s は空、もしくは、小文字の a-z だけを含むことができます。
p は空、もしくは、小文字の a-z と . や * のような文字のみを含むことができます。
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab".
Input:
s = "mississippi"
p = "mis*is*p*."
Output: false
class Solution(object):
def isMatch(self, text, pattern):
"""
:type s: str
:type p: str
:rtype: bool
"""
memo = {}
def dp(i, j):
if (i, j) not in memo:
if j == len(pattern):
ans = i == len(text)
else:
first_match = i < len(text) and pattern[j] in {text[i], '.'}
if j+1 < len(pattern) and pattern[j+1] == '*':
ans = dp(i, j+2) or first_match and dp(i+1, j)
else:
ans = first_match and dp(i+1, j+1)
memo[i, j] = ans
return memo[i, j]
return dp(0, 0)
11. Container With Most Water
n 個の非負の整数 a1, a2, ..., an があるとき,それぞれ座標 (i, ai) の点を表す.x軸と一緒に容器を形成する2本の線を求め,その容器が最も多くの水を含むようにしなさい.
注意
容器を斜めにしてはいけない、nは2以上である。
Input: [1,8,6,2,5,4,8,3,7]
Output: 49
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
water = 0
head = 0
tail = len(height) - 1
for cnt in range(len(height)):
width = abs(head - tail)
if height[head] < height[tail]:
res = width * height[head]
head += 1
else:
res = width * height[tail]
tail -= 1
if res > water:
water = res
return water
14. Longest Common Prefix
文字列の配列の中から、最も長い共通接頭辞文字列を見つける関数を書きます。
共通接頭辞がない場合は、空の文字列 "" を返します。
Input: ["flower","flow","flight"]
Output: "fl"
Input: ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
注意
すべての入力は小文字のa-zである。
class Solution:
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
prefix = ""
if len(strs)==0: return prefix
for i in range(len(min(strs))):
c=strs[0][i]
if all(a[i]==c for a in strs):
prefix+=c
else:
break
return prefix
16. 3Sum Closest
n 個の整数の配列 nums と整数のターゲットが与えられた場合、nums の中から和がターゲットに最も近くなるような 3 つの整数を求めます。3つの整数の和を返します.それぞれの入力が正確に1つの解を持つと仮定してもよい。
Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
条件
3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4
class Solution(object):
def threeSumClosest(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
diff = float('inf')
nums.sort()
for i in range(len(nums)):
lo, hi = i + 1, len(nums) - 1
while (lo < hi):
sum = nums[i] + nums[lo] + nums[hi]
if abs(target - sum) < abs(diff):
diff = target - sum
if sum < target:
lo += 1
else:
hi -= 1
if diff == 0:
break
return target - diff
19. Remove Nth Node From End of List
リンクされたリストが与えられた場合、リストの末尾からn番目のノードを削除し、その先頭を返します。
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
注意
与えられたnは常に有効です。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
length, count, dummy = 1, 1, head
while dummy.next:
length, dummy = length + 1, dummy.next
dummy = head
if length == n: return head.next
while count < length - n:
count, dummy = count + 1, dummy.next
dummy.next = dummy.next.next
return head
20. Valid Parentheses
文字 '(', ')', '{', '}', '[' および ']' だけを含む文字列が与えられた場合、入力された文字列が有効かどうかを判断します。
入力文字列は、以下の場合に有効です。
1. オープンブラケットは、同じ種類のブラケットで閉じなければなりません。
2. 開いているカッコは、正しい順序で閉じなければなりません。
空の文字列も有効とみなされることに注意してください。
Input: "()"
Output: true
Input: "()[]{}"
Output: true
Input: "(]"
Output: false
Input: "([)]"
Output: false
Input: "{[]}"
Output: true
class Solution(object):
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
stack = []
mapping = {")": "(", "}": "{", "]": "["}
for char in s:
if char in mapping:
top_element = stack.pop() if stack else '#'
if mapping[char] != top_element:
return False
else:
stack.append(char)
return not stack
22. Generate Parentheses
n組の括弧が与えられたとき、形の整った括弧のすべての組み合わせを生成する関数を書きなさい。
例えば、n = 3が与えられると、解の集合は次のようになります。
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
class Solution(object):
def generateParenthesis(self, n):
"""
:type n: int
:rtype: List[str]
"""
ans = []
def backtrack(S = '', left = 0, right = 0):
if len(S) == 2 * n:
ans.append(S)
return
if left < n:
backtrack(S+'(', left+1, right)
if right < left:
backtrack(S+')', left, right+1)
backtrack()
return ans
Author And Source
この問題について([Python] [LeetCode] [競技プログラミング]), 我々は、より多くの情報をここで見つけました https://qiita.com/YusukeEngineer/items/43bb1c1339f022db7ce0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .