1. Two Sum
Given an array of integers nums
and an integer target
, return indices of the two numbers such that they add up to target
.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
You can return the answer in any order.
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Output: Because nums[0] + nums[1] == 9, we return [0, 1].
Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]
Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
nums_dict={}
for i, n in enumerate( nums ):
if n in nums_dict:
return [nums_dict[n],i]
#else: # another number is target-n
nums_dict[target-n]=i # target-n : the index ofcurrent number
2. Add Two Numbers
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example 1:
Input: l1 = [2,4,3], l2 = [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 = 807.
Example 2:
Input: l1 = [0], l2 = [0]
Output: [0]
Example 3:
Input: l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]
# 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 addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
p=s=ListNode(0)
while p!=None:
total=0
if l1 !=None:
total += l1.val
l1 = l1.next
if l2 !=None:
total += l2.val
l2 = l2.next
total += p.val
p.val=total%10
if l1 !=None or l2 !=None or total>=10:
p.next=ListNode(total//10)
else:
p.next=None
p=p.next
return s
3. Longest Substring Without Repeating Characters
Given a string s
, find the length of the longest substring without repeating characters.
Example 1:
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
Example 4:
Input: s = ""
Output: 0
if statement with max replace while loop for empty the Sliding Window
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
window={} # {char:index}
w_left_i=0
max_len=0
for w_right_i, c in enumerate(s):
if c in window:
# since "while c in window:" will
# empty the window from left to right until c not in the window
w_left_i = max( window[c]+1, w_left_i ) # time(less) to memory
window[c] = w_right_i
if max_len < ( w_right_i - w_left_i +1 ):
max_len= w_right_i - w_left_i +1
return max_len
# memory(less) to time
# window=set()
# w_left_i=0
# max_len=0
# for w_right_i, c in enumerate(s):
# while c in window: # empty the window from left to right until c not in the window
# window.remove( s[w_left_i] ) # remove c at w_left_i
# w_left_i +=1
# # At first, if c not in w:
# window.add(c) # hidden: right_i+=1 and expand the size of window
# if max_len < ( w_right_i - w_left_i +1 ):
# max_len= w_right_i - w_left_i +1
# return max_len
4. Median of Two Sorted Arrays
Given two sorted arrays nums1
and nums2
of size m
and n
respectively, return the median of the two sorted arrays.
The overall run time complexity should be O(log (m+n))
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
Example 3:
Input: nums1 = [0,0], nums2 = [0,0]
Output: 0.00000
Example 4:
Input: nums1 = [], nums2 = [1]
Output: 1.00000
Example 5:
Input: nums1 = [2], nums2 = []
Output: 2.00000
class Solution(object):
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
m=[]
m.extend(nums1)
m.extend(nums2)
m.sort()
if len(m)==0:
return None
if len(m) & 1 == 1: # '&1' is faster than '%2'
return m[len(m)/2]
# else: # len(m) %2==0 means even numbers
return ( m[ len(m)/2 ] + m[ len(m)/2-1 ] )/2.
5. Longest Palindromic Substring
Given a string s
, return the longest palindromic substring in s
.
Example 1:
Input: s = "babad"
Output: "bab"
Note: "aba" is also a valid answer.
Example 2:
Input: s = "cbbd"
Output: "bb"
Example 3:
Input: s = "a"
Output: "a"
Example 4:
Input: s = "ac"
Output: "a"
我用的是左下角部分
- if all characters in the string s are same, then return s
- otherwise, if the len(s) ==2, return the first character directly
- create a matrix with rows*columns = len(s) * len(s), and filled with the False(0)
- use the out layer of for loop traverse the rows,
- use the inner loop traverse the columns and columns' index is from 0 to row_index since I just use the bottom-left cells under the reverse diagnoal.
if the current row character (of index == row_index) is equal to current column character(of index == column_index),
and
the difference between row_index and column_index is less than 2 that mean the current row character and current column character are neighbor(are palindrome) or inner characters between current cell and the cell on the diagnoal are palindrome as well, then current cell will be assigned 1
(The idea of dynamic programming is to ensure that the solution to the sub-problem is optimal (here, the internal character is the palindrome), and then the solution to the subsequent problem is also optimal (here, one character is extended on both sides to ensure that a new and longer palindrome is formed)
) - the cell which the column character's index is equal the row character's index, in other words, the cell on the diagnoal, then it will be assigned with 1
(after inner loop fill the diagnoal cell with True(1)) - go to next row
- Certainly , in the inner loop, we have to check the current palindrome whether is the longest
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
# if all charater in s are same
if len( set(s) ) ==1:
return s
n=len(s)
if n==2: # and s[0] != s[1]
return s[0]
##### Dynamic programming #####
# create an nxn matrix
dp = [[False]*n for _ in range(n) ] # n_rows x n_columns
start, end, maxLen = 0,0,0
for i in range(n): # along row axis
for j in range(i): # along column axis # 0<=j <i ##################
# s[i] == s[j]
# same character if j==i # j-i<=1 # j-i<2
# Adjacent characters if j-i=1 # j-i<=1 # j-i<2
# non-Adjacent characters if j-i>1 # j-i>=2
# j-i>=2 we need to check previous row in the dp matrix, dp[i-1][j+1]
# but not need to check dp[i-1][i-1] since the value of the diagonal is always True
# use bottom-left cells in the maxtrix ==> 0<=j<i
dp[i][j] = ( s[i] == s[j] ) & ( (i-j<2) | dp[i-1][j+1] )
if dp[i][j] and i-j+1>maxLen:
maxLen=i-j+1
start = j
end = i
dp[i][i] = True #dp[i][i]= dp[i][j+1]
return s[start:end+1]
返回最长回文数目:
s = "dacabacad" # 'd a c a b a c a d'
# '#'.join(s) ==> 'd#a#c#a#b#a#c#a#d'
new_s = '$#' + '#'.join(s) + '#$'
# new_s : '$#d#a#c#a#b#a#c#a#d#$'
length_new_s = len(new_s)
count_1_side=[0]*length_new_s
L, R = 0, 0
for i in range(1, length_new_s_s-1 ):
# step 3
# if current R is right edge of the previous Palindromic
# in other words, i is on the right part of previous Palindromic
# and j is symmetry point of i,
# the center index of previous Palindromic, 2*L-i
if i<R:
p[i] = min( count_1_side[2*L-i], R-i)
# right size # left size
while new_s[ i+1+ count_1_side[i] ] == new_s[ i-1- count_1_side[i] ]: # step 1
count_1_side[i]+=1
if i+count_1_side[i] > R: # step 2
R = i+count_1_side[i] # the right-edge index of current Palindromic
L = i # the center index of current Palindromic
return count_1_side # the Longest Palindromic Substring
# The length of the longest palindrome in the original string is equal to
# the length of one side of the center symmetry point of
# the palindrome after insertion processing
6. ZigZag Conversion
The string "PAYPALISHIRING"
is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P A H N
A P L S I I G
Y I R
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string s, int numRows);
Example 1:
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"
Example 2:
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:
P I N
A L S I G
Y A H R
P I
Example 3:
Input: s = "A", numRows = 1
Output: "A"
- if the numRows==1 or the len(s) <=numRows, then we can directly return the string s
- otherwise, we create a empty string list s_list with the length that is equal to numRows
- There is a rule here. The character of s is filled down according to the row index(s_list[row_index] , deep=1 and row_index +=deep). When the number of rows is equal to numRows(current row_index == numRows-1), go to next column and return to the previous row (meaning that the row index is reduced, deep-=1) until it returns to the first row and then goes down again.
class Solution(object):
def convert(self, s, numRows):
"""
:type s: str
:type numRows: int
:rtype: str
"""
# one row # one column
if numRows==1 or len(s) <= numRows:
return s
s_list=["",]*numRows
row_index=0
deep=1
for c in s:
s_list[row_index] = s_list[row_index]+c
if row_index==0: # stop on first row
deep=1 # walk down
if row_index==numRows-1: # stop on last row
deep=-1 # walk up
row_index += deep
return ''.join(s_list)
7. Reverse Integer
Given a signed 32-bit integer x
, return x
with its digits reversed. If reversing x
causes the value to go outside the signed 32-bit integer range [-2^31, 2^31 - 1]
, then return 0
.
Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
Example 1:
Input: x = 123
Output: 321
Example 2:
Input: x = -123
Output: -321
Example 3:
Input: x = 120
Output: 21
Example 4:
Input: x = 0
Output: 0
- if x==0, then return 0
- if x<0 then sign=-1, otherwise, sign=1. so we can let x become positive firstly,
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
# if x==0:
# return 0
# digit_list=[]
# sign=1
# if x < 0:
# sign=-1
# x/=sign
# while x>0:
# digit_list.append(x%10)
# x/=10
# digit_list=list( reversed(digit_list) )
# value=0
# for i in range( len(digit_list) ):
# value+=digit_list[i]*10**i
# value*=sign
# if value >(2**31-1) or value<(-2**31): # memory cost
# return 0
# else:
# return value
if x==0:
return 0
sign=1
if x<0:
sign=-1
x/=sign
x_str=str(x)
try:
value = int( x_str[::-1] )*sign
except:
0
# if abs(value) < 0xffffffff/2: # time cost
# return value
# else:
# return 0
if value >(2**31-1) or value<(-2**31): # memory cost
return 0
else:
return value
8. String to Integer (atoi)
Implement the myAtoi(string s)
function, which converts a string to a 32-bit signed integer (similar to C/C++'s atoi
function).
The algorithm for myAtoi(string s)
is as follows:
- Read in and ignore any leading whitespace.
- Check if the next character (if not already at the end of the string) is
'-'
or'+'
. Read this character in if it is either. This determines if the final result is negative or positive respectively. Assume the result is positive if neither is present. - Read in next the characters until the next non-digit charcter or the end of the input is reached. The rest of the string is ignored.
- Convert these digits into an integer (i.e.
"123" -> 123
,"0032" -> 32
). If no digits were read, then the integer is0
. Change the sign as necessary (from step 2). - If the integer is out of the 32-bit signed integer range
[-2^31, 2^31 - 1]
, then clamp the integer so that it remains in the range. Specifically, integers less than-231
should be clamped to-231
, and integers greater than231 - 1
should be clamped to231 - 1
. - Return the integer as the final result.
Example 1:
Input: s = "42" # ==> int()
Output: 42
Explanation: The underlined characters are what is read in, the caret is the current reader position.
Step 1: "42" (no characters read because there is no leading whitespace)
^
Step 2: "42" (no characters read because there is neither a '-' nor '+')
^
Step 3: "42" ("42" is read in)
^
The parsed integer is 42.
Since 42 is in the range [-231, 231 - 1], the final result is 42.
Example 2:
Input: s = " -42" # ==> s=s.split() # return a substring list # # split() default 以空格为分隔符,包含 \n, 返回分割后的字符串列表。
Output: -42
Explanation:
Step 1: " -42" (leading whitespace is read and ignored)
^
Step 2: " -42" ('-' is read, so the result should be negative)
^
Step 3: " -42" ("42" is read in)
^
The parsed integer is -42.
Since -42 is in the range [-231, 231 - 1], the final result is -42.
Example 3:
Input: s = "4193 with words" # ==> s=s.split() # return a substring list # # split() default 以空格为分隔符,包含 \n, 返回分割后的字符串列表。
Output: 4193
Explanation:
Step 1: "4193 with words" (no characters read because there is no leading whitespace)
^
Step 2: "4193 with words" (no characters read because there is neither a '-' nor '+')
^
Step 3: "4193 with words" ("4193" is read in; reading stops because the next character is a non-digit)
^
The parsed integer is 4193.
Since 4193 is in the range [-231, 231 - 1], the final result is 4193.
Example 4:
Input: s = "words and 987"
Output: 0
Explanation:
Step 1: "words and 987" (no characters read because there is no leading whitespace)
^
Step 2: "words and 987" (no characters read because there is neither a '-' nor '+')
^
Step 3: "words and 987" (reading stops immediately because there is a non-digit 'w')
^
The parsed integer is 0 because no digits were read.
Since 0 is in the range [-231, 231 - 1], the final result is 0.
Example 5:
Input: s = "-91283472332"
Output: -2147483648
Explanation:
Step 1: "-91283472332" (no characters read because there is no leading whitespace)
^
Step 2: "-91283472332" ('-' is read, so the result should be negative)
^
Step 3: "-91283472332" ("91283472332" is read in)
^
The parsed integer is -91283472332.
Since -91283472332 is less than the lower bound of the range [-2^31, 2^31 - 1], the final result is clamped to -2^31 = -2147483648.
Input:
"-2147483647"
"+-12"
"3.14159"
Expected:
-2147483647
0
3
class Solution(object):
def myAtoi(self, s):
"""
:type s: str
:rtype: int
"""
s=s.split() # return a substring list
length=len(s)
if len(s)==0:
return 0
c=ord( s[0][0] )
sign=1
if c==45: # if '-'
sign=-1
s[0]=s[0][1:]
elif c==43: # if '+'
s[0]=s[0][1:]
end=0
while end<len(s[0]):
if ord( s[0][end] )<48 or ord(s[0][end]) >57:
break
end+=1
s[0]=s[0][:end]
#try:
n=int(s[0]) *10//10
if n*sign < -2**31:
return -2**31
elif n*sign> 2**31 - 1:
return 2**31 - 1
else:
return n*sign
#except:
# return 0
ValueError: invalid literal for int() with base 10: ''
n=int(s[0]) *10//10
Line 31 in myAtoi (Solution.py)
ret = Solution().myAtoi(param_1)
Line 60 in _driver (Solution.py)
_driver()
Line 70 in (Solution.py)
Solution:
class Solution(object):
def myAtoi(self, s):
"""
:type s: str
:rtype: int
"""
s=s.split() # return a substring list
length=len(s)
if len(s)==0: # empty string
return 0
c=ord( s[0][0] )
# extract number from s[0] and store the symbol
sign=1
if c==45: # if '-'
sign=-1
s[0]=s[0][1:]
elif c==43: # if '+'
s[0]=s[0][1:]
# traverse the character and stop when encounter the non-digit charater
end=0
while end<len(s[0]):
if ord( s[0][end] )<48 or ord(s[0][end]) >57:
break
end+=1
s[0]=s[0][:end]
try:
n=int( float(s[0]) *10 )//10
if n*sign < -2**31:
return -2**31
elif n*sign> 2**31 - 1:
return 2**31 - 1
else:
return n*sign
except:
return 0
9. Palindrome Number
Given an integer x
, return true
if x
is palindrome integer.
An integer is a palindrome when it reads the same backward as forward. For example, 121
is palindrome while 123
is not.
Example 1:
Input: x = 121 # extract digit from left to right #==> reverted = reverted*10 + x%10 , x/=10 # and while x>reverted loop: for ignore the middle
Output: true #and consider the odd number after while loop and x/=10 ==> x==1, and reverted==12 ==> x==reverted/10
Example 2:
Input: x = -121 # if x<0 return False
Output: false
Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:
Input: x = 10 # if (x%10==0 and x!=0 since 0 is a a palindrome) return False
Output: false
Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
Example 4:
Input: x = -101
Output: false
class Solution(object):
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
# if x<0:
# return False
# try:
# x_str=list(str(x))
# len_x=len(x_str)
# if len_x % 2==0:
# x_str.insert(len_x/2, 0)
# len_x+=1
# for i in range(len_x/2):
# if x_str[i] != x_str[len_x-1-i]:
# return False
# return True
# except:
# return False
if x<0 or (x%10==0 and x!=0) :
return False
reverted=0
while x>reverted:
reverted = reverted*10 + x%10
x/=10
# even # odd number
return x==reverted or x==reverted/10
10. Regular Expression Matching
Given an input string (s
) and a pattern (p
), implement regular expression matching with support for '.'
and '*'
where:
'.'
Matches any single character.'*'
Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Example 1:
Input: s = "aa", p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
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".
Example 3:
Input: s = "ab", p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Example 4:
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".
Example 5:
Input: s = "mississippi", p = "mis*is*p*."
Output: false
class Solution(object):
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
# https://blog.csdn.net/Linli522362242/article/details/90139705
import re
# re.match(pattern, string, flags=0)
return re.match("^"+p+"$", s)
11. Container With Most Water
Given n
non-negative integers a1, a2, ..., an
, where each represents a point at coordinate (i, ai)
. n
vertical lines are drawn such that the two end points of the line i
is at (i, ai)
and (i, 0)
. Find two lines, which, together with the x-axis forms a container, such that the container contains the most water.
Notice that you may not slant the container.
# hint: the difference between the indexes of two end points is used as the width of area
Example 1:
Input: height = [1,8,6,2,5,4,8,3,7]
Output: 49
Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
Example 2:
Input: height = [1,1]
Output: 1
Example 3:
Input: height = [4,3,2,1,4]
Output: 16
Example 4:
Input: height = [1,2,1]
Output: 2
- from outside to inside by moving pointers 'L' and 'R',
- One of the pointers ('L' and 'R') will point to the max value of height that reduce the frequent movement of the pointer in the double loop
- Fix one of the pointers('L' or 'R') which point to the large value of height for current area, then move the pointer which point to the small value of height for current area
- hint: the difference between the indexes of two end points is used as the width of area, I use the width as the for loop condition
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
# hint: the difference between the indexes of two points is used as the width
# Time Limit Exceeded
# n = len(height)
# max_area=0
# for i in range( n-1 ): # [0, left_end)
# for j in range( i+1, n ): #[right_start, n)
# # h = height[j] if height[i] > height[j] else height[i]
# h=min(height[i], height[j])
# # if (j-i)*h >max_area:
# # max_area=(j-i)*h
# max_area = max( (j-i)*h, max_area )
# return max_area
# from outside to inside by moving pointers 'L' and 'R',
# One of the pointers ('L' and 'R') will point to the max value of height that
# reduce the frequent movement of the pointer in the double loop
L, R, width, max_area = 0, len(height)-1, len(height)-1, 0
for w in range(width, 0, -1):
if height[L] < height[R]: # move index 'L' to right
max_area, L = max(max_area, height[L]*w), L+1
else:
max_area, R = max(max_area, height[R]*w), R-1
return max_area
12. Integer to Roman
Roman numerals are represented by seven different symbols: I
, V
, X
, L
, C
, D
and M
.
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, 2
is written as II
in Roman numeral, just two one's added together. 12
is written as XII
, which is simply X + II
. The number 27
is written as XXVII
, which is XX + V + II
.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII
. Instead, the number four is written as IV
. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX
. There are six instances where subtraction is used:
I
can be placed beforeV
(5) andX
(10) to make 4 and 9.
(### 4 : 'IV' and 9 : 'IX' ### )X
can be placed beforeL
(50) andC
(100) to make 40 and 90.
(### 40 : 'XL', and 90 : 'XC', ### )C
can be placed beforeD
(500) andM
(1000) to make 400 and 900.
(### 400 : 'CD', and 900: 'CM', ### )
Given an integer, convert it to a roman numeral.
Example 1:
Input: num = 3
Output: "III"
Example 2:
Input: num = 4
Output: "IV"
Example 3:
Input: num = 9
Output: "IX"
Example 4:
Input: num = 58
Output: "LVIII"
Explanation: L = 50, V = 5, III = 3.
Example 5:
Input: num = 1994
Output: "MCMXCIV"
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
class Solution(object):
def intToRoman(self, num):
"""
:type num: int
:rtype: str
"""
value_symbol={
1000: 'M',
900: 'CM', ###
500 : 'D',
400 : 'CD', ###
100 : 'C',
90 : 'XC', ###
50 : 'L',
40 : 'XL', ###
10 : 'X',
9 : 'IX', ###
5 : 'V',
4 : 'IV', ###
1 : 'I',
}
s=""
# value_symbol.keys() will sort they keys automatically
for v in sorted( value_symbol.keys(), reverse=True ):
while num >= v:
num -= v
s += value_symbol[v]
# # for python 3
# for v,c in value_symbol.items():
# while num >= v:
# num -= v
# s += c
return s
13. Roman to Integer
Roman numerals are represented by seven different symbols: I
, V
, X
, L
, C
, D
and M
.
Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
For example, 2
is written as II
in Roman numeral, just two one's added together. 12
is written as XII
, which is simply X + II
. The number 27
is written as XXVII
, which is XX + V + II
.
Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII
. Instead, the number four is written as IV
. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX
. There are six instances where subtraction is used:
I
can be placed beforeV
(5) andX
(10) to make 4 and 9.X
can be placed beforeL
(50) andC
(100) to make 40 and 90.C
can be placed beforeD
(500) andM
(1000) to make 400 and 900.
Given a roman numeral, convert it to an integer.
Example 1:
Input: s = "III"
Output: 3
Example 2:
Input: s = "IV"
Output: 4
Example 3:
Input: s = "IX"
Output: 9
Example 4:
Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.
Example 5:
Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
class Solution:
def romanToInt(self, s: str) -> int:
symbol_value={
'M' : 1000,
'D' : 500,
'C' : 100,
'L' : 50,
'X' : 10,
'V' : 5,
'I' : 1,
}
num_list=[]
for c in s:
num_list.append( symbol_value[c] )
n=0
for i in range( len( num_list) ):
# Note: we can't not use 'if num_list[i-1]' since backend will assign an number(e.g. -1) to num_list[-1]
if i>0 and num_list[i-1]<num_list[i]:
n-=num_list[i-1]*2
n+=num_list[i]
else:
n+=num_list[i]
return n
14. Longest Common Prefix
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string ""
.
Example 1:
Input: strs = ["flower","flow","flight"]
Output: "fl"
Example 2:
Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.
class Solution:
def longestCommonPrefix(self, strs: List[str]) -> str:
if len(strs)==1:
return strs[0]
# 0 <= strs[i].length <= 200
min_len = len(strs[0]) # faster than min_len=200
for str in strs:
min_len = min( min_len, len(str) )
if min_len==0:
return ""
count=0
for i in range(min_len):
for j in range( 1, len(strs) ):
if strs[0][i] != strs[j][i]:
return strs[0][:count]
count+=1
if i==min_len-1: # if min_len==1 ############
return strs[0][:count]
15. 3Sum
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]]
such that i != j
, i != k
, and j != k
, and nums[i] + nums[j] + nums[k] == 0
.
Notice that the solution set must not contain duplicate triplets.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Example 2:
Input: nums = []
Output: []
Example 3:
Input: nums = [0]
Output: []
Input : [0,0,0]
Output : [[0,0,0]]
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
if len(nums)<3 : # since the question require at 3 numbers for return a triplet
return []
if len( nums )==3 and sum(nums)==0: # only 3 numbers
return [nums]
n=len(nums)
nums.sort() # 1st step for the flowing processes
triplet_list=[]
record_k_for_next_i=0
for i in range(n-2):
if nums[i]>0: # 2nd step since nums[i]<nums[j]<nums[k] after sorting
return triplet_list
if i>0 and nums[i] == nums[i-1]: # 5th step
continue
j=i+1
k=n-1-record_k_for_next_i
while j<k:
# 3rd step
t = nums[i] + nums[j] + nums[k] # note: num[i]<= smallest<=nums[j] <= nums[k]<== largest if I freeze nums[i]
if t<0 : # means num[j] is too small, move j to right
j+=1
continue
elif t>0 : # means num[k] is too large, move k to left
# since start the next i loop, nums[i] and num[j] will be greater, num[k] cannot use current the largest value if t>0
if j==i+1 and k== n-1 -record_k_for_next_i:
record_k_for_next_i +=1
k-=1
continue
else: # t==0
triplet_list.append( [ nums[i],nums[j], nums[k] ] )
# 4th step
while j+1<k and nums[j]==nums[j+1]: # if the next number is same with the current number, we can jump it for reducing repeated append action
j+=1
while j<k-1 and nums[k]==nums[k-1]:
k-=1
j+=1 # for next i loop
k-=1
return triplet_list
# time Time Limit Exceeded
# for j in range(i+1, n-1):
# for k in range(n-1, j,-1):
# if nums[k]<0:
# break
# #print(' nums[i],nums[j], nums[k]', nums[i],nums[j], nums[k])
# if nums[i] + nums[j] + nums[k] ==0:
# check=True
# if len(triplet_list) >0 :
# x=0
# while x<len(triplet_list) and check :
# # compare 2 list cannot use ==
# if triplet_list[x][0]==nums[i] and triplet_list[x][1]==nums[j] and triplet_list[x][2]==nums[k]:
# check=False
# break
# else:
# x+=1
# if check:
# triplet_list.append( [ nums[i],nums[j], nums[k] ] )
return triplet_list
16. 3Sum Closest
Given an array nums
of n integers and an integer target
, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example 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).
Constraints:
3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
if len(nums) == 3:
return nums[0]+nums[1]+nums[2]
n=len(nums)
nums.sort() # for the later process, min<= nums[j] <= nums[k] <= max
min_diff=float("inf") # faster than min_diff=10000 since -10^4 <= target <= 10^4
record_k_for_next_i = 0
# minimize: abs( num[i]+num[j]+num[i]-target ) return num[i]+num[j]+num[i]
# minimize: abs( target-num[i]-num[j]-num[i] )
# return: target-( target-num[i]-num[j]-num[i] )
for i in range(n-2):
deducted = target-nums[i]
j=i+1
k = n-1 -record_k_for_next_i
while(j<k):
diff = deducted-nums[j]-nums[k]
if abs(diff) < abs(min_diff):
min_diff = diff
if diff>0 : # mean num[i]+num[j]+num[i] too small # < target
j+=1
continue
elif diff<0 : # mean num[i]+num[j]+num[i] too large # > target
if j==i+1 and k==n-1-record_k_for_next_i: # since next i loop nums[i] and nums[j] are greater
record_k_for_next_i +=1
k-=1
continue
else: # diff==0
return target
return target-min_diff
17. Letter Combinations of a Phone Number
Given a string containing digits from 2-9
inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.
A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
Example 1:
Input: digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
Example 2:
Input: digits = ""
Output: []
Example 3:
Input: digits = "2"
Output: ["a","b","c"]
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
if len(digits) ==0 :
return []
digit_letters = { '2':['a', 'b', 'c'],
'3':['d', 'e', 'f'],
'4':['g', 'h', 'i'],
'5':['j', 'k', 'l'],
'6':['m', 'n', 'o'],
'7':['p', 'q', 'r', 's'],
'8':['t', 'u', 'v'],
'9':['w', 'x', 'y', 'z'],
}
if len(digits) ==1:
return digit_letters[digits]
# combinations=[]
# def recursiveMerge( combination, merged_c, index):
# if index==len(digits):
# combinations.append( merged_c )
# return combinations
# for c in digit_letters[ digits[index] ]: # use for loop to traverse the charcter(letter) in dict's value-list
# recursiveMerge( combinations, # 'a' x ['d', 'e', 'f'] ==> recursiveMerge
# merged_c+c, # 'b' x ['d', 'e', 'f']
# index+1 # 'c' x ['d', 'e', 'f']
# )
# recursiveMerge( combinations, '', 0)
# # if digits="23", digits[index=0] ==> '2':['a', 'b', 'c']
# # ==> recursiveMerge ==> for loop ==> index=0, c='a' ==> ''+'a' and index+1 ==> recursiveMerge
# # digits[index=1] ==> '3':['d', 'e', 'f'],
# # ==> for loop ==> index=1, c='d' ==> ''+'a'+'d' and index+1 ==> recursiveMerge ==> append /
# # ==> index=1, c='e' ==> ''+'a'+'e' and index+1 ==> recursiveMerge ==> append /
# # ==> index=1, c='f' ==> ''+'a'+'f' and index+1 ==> recursiveMerge ==> append /
# # ==> recursiveMerge ==> for loop ==> index=0, c='b' ==> ''+'b' and index+1 ==> recursiveMerge
# # ...
# return combinations
combinations=['',]
for d in digits: # broadcasting
combinations = [ merged+c for merged in combinations for c in digit_letters[d] ]
# if digits="23", for c in digit_letters[d] ==> '2':['a', 'b', 'c']
# for merged in combinations ==> '' ==>
# '' + broadcasting( ''+'a', # for c loop
# ''+'b', # for c loop
# ''+'c' # for c loop
# )==> combinations=['a', 'b', 'c']
# for c in digit_letters[d] ==> '3':['d', 'e', 'f']
# for merged in combinations ==> 'a', 'b', 'c' ==>
# 'a', 'b', 'c' + broadcasting( 'a'+'d', 'b'+'d', 'c'+'d' ; # for c loop
# 'a'+'e', 'b'+'e', 'c'+'e' ; # for c loop
# 'a'+'f', 'b'+'f', 'c'+'f' # for c loop
# )
return combinations
18. 4Sum
Given an array nums
of n
integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]]
such that:
0 <= a, b, c, d < n
a
,b
,c
, andd
are distinct.nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
Example 1:
Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Example 2:
Input: nums = [2,2,2,2,2], target = 8
Output: [[2,2,2,2]]
Constraints:
1 <= nums.length <= 200
-109 <= nums[i] <= 109
-109 <= target <= 109
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
if len(nums) <4:
return []
if len(nums)==4 and sum(nums) !=target:
return []
elif len(nums)==4 and sum(nums) ==target:
return [nums]
n=len(nums)
nums.sort() # step 1
quadruplet_list=[]
for i in range( n-3): # 0 <= i < n-3 # 3 for L(n-3),R(n-2),j(n-1)
if i>0 and nums[i]==nums[i-1]: ### De-duplication
continue ### De-duplication
decucted = target-nums[i]
for j in range(n-1, i+2, -1): # n-1>= j > i+2 # i(i+0),L(i+1),R(i+2)
if j<n-1 and nums[j]==nums[j+1]: ### De-duplication
continue ### De-duplication
decucted2 = decucted-nums[j] ###### can't use deducted = decucted-nums[j] #######
L=i+1
R=j-1
while(L<R):
diff = decucted2 - nums[L] - nums[R]
if diff >0 : # too small # nums[a] + nums[b] + nums[c] + nums[d] < target
L+=1
continue # while loop
elif diff <0 : # too large # nums[a] + nums[b] + nums[c] + nums[d] < target
R-=1
continue # while loop
else:
# more memory but faster than 'if i>0 and nums[i]==nums[i-1]:' and 'if j<n-1 and nums[j]==nums[j+1]:'
# Replaced ##
# if_append=True
# for q in quadruplet_list:
# if q[0]==nums[i] and q[1]==nums[L] and q[2]==nums[R] and q[3]==nums[j]:
# if_append=False
# break # exit for loop
# if if_append:
# quadruplet_list.append([ nums[i], nums[L], nums[R], nums[j] ])
# ###De-duplication
quadruplet_list.append([ nums[i], nums[L], nums[R], nums[j] ])
while L+1<R and nums[L]==nums[L+1]: ### De-duplication
L+=1
while L<=R-1 and nums[R]==nums[R-1]: ### De-duplication
R-=1
# ###De-duplication
L+=1
R-=1
return quadruplet_list
OR
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
if len(nums) <4:
return []
if len(nums)==4 and sum(nums) !=target:
return []
elif len(nums)==4 and sum(nums) ==target:
return [nums]
n=len(nums)
nums.sort() # step 1
quadruplet_list=[]
for i in range( n-3): # 0 <= i < n-3 # 3 for L(n-3),R(n-2),j(n-1)
# if i>0 and nums[i]==nums[i-1]: ### De-duplication
# continue ### De-duplication
decucted = target-nums[i]
for j in range(n-1, i+2, -1): # n-1>= j > i+2 # i(i+0),L(i+1),R(i+2)
# if j<n-1 and nums[j]==nums[j+1]: ### De-duplication
# continue ### De-duplication
decucted2 = decucted-nums[j] ###### can't use deducted = decucted-nums[j] #######
L=i+1
R=j-1
while(L<R):
diff = decucted2 - nums[L] - nums[R]
if diff >0 : # too small # nums[a] + nums[b] + nums[c] + nums[d] < target
L+=1
continue # while loop
elif diff <0 : # too large # nums[a] + nums[b] + nums[c] + nums[d] < target
R-=1
continue # while loop
else:
# more memory but faster than 'if i>0 and nums[i]==nums[i-1]:' and 'if j<n-1 and nums[j]==nums[j+1]:'
# Replaced ##
if_append=True
for q in quadruplet_list:
if q[0]==nums[i] and q[1]==nums[L] and q[2]==nums[R] and q[3]==nums[j]:
if_append=False
break # exit for loop
if if_append:
quadruplet_list.append([ nums[i], nums[L], nums[R], nums[j] ])
# ###De-duplication
# quadruplet_list.append([ nums[i], nums[L], nums[R], nums[j] ])
# while L+1<R and nums[L]==nums[L+1]: ### De-duplication
# L+=1
# while L<=R-1 and nums[R]==nums[R-1]: ### De-duplication
# R-=1
# ###De-duplication
L+=1
R-=1
return quadruplet_list
19. Remove Nth Node From End of List
Given the head
of a linked list, remove the nth
node from the end of the list and return its head.
Example 1:
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
Example 2:
Input: head = [1], n = 1
Output: []
Example 3:
Input: head = [1,2], n = 1
Output: [1]
Constraints:
- The number of nodes in the list is
sz
. 1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
# # 1 <= The number of nodes
# # 1 <= n <= The number of nodes
# move = head.next
# if move == None: # only one node in the head
# return head.next
# last_index=1
# while move.next != None:
# move=move.next
# last_index+=1
# # print(index) # 4
# # index: [0,1,2,3,4]
# # value: [1,2,3,4,5]
# if last_index+1-n==0: # remove the first node
# return head.next
# # pre
# # |
# # V
# # index: [0,1,2,3,4]
# # value: [1,2,3,4,5]
# # ^
# # |
# # move
# pre=head
# move = head.next
# for i in range( 1,last_index+1-n ):
# pre=move
# move = move.next
# # end of for loop, move is the node I want to remove
# pre.next = move.next
# return head
# 1 <= The number of nodes
# 1 <= n <= The number of nodes
right_range_node = head
for _ in range(n): # n>=1
right_range_node = right_range_node.next
# end of for loop, the distance between head and right_range_node is n
# e.g. The number of nodes = 1 : [1]
# right_range_node (The number of nodes == n)
# |
# V
# head --> 1 --> None
# OR The number of nodes = 2 : [1,2]
# right_range_node (The number of nodes == n)
# |
# V
# head --> 1 --> 2 --> None
if right_range_node == None: # means n==The number of nodes ==> remove the first node
return head.next
# else : n<The number of nodes ==> remove not first node
before_remove_node = head #the distance between before_remove_node and right_range_node is n
while right_range_node.next !=None:
right_range_node = right_range_node.next
before_remove_node = before_remove_node.next
# end of for loop, the previous node of the removed node : before_remove_node
# before_remove_node.next :the node I want to remove
before_remove_node.next = before_remove_node.next.next
return head
OR
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
# 1 <= The number of nodes
# 1 <= n <= The number of nodes
move = head.next
if move == None: # only one node in the head
return head.next
last_index=1
while move.next != None:
move=move.next
last_index+=1
# print(index) # 4
# index: [0,1,2,3,4]
# value: [1,2,3,4,5]
if last_index+1-n==0: # remove the first node
return head.next
# pre
# |
# V
# index: [0,1,2,3,4]
# value: [1,2,3,4,5]
# ^
# |
# move
pre=head
move = head.next
for i in range( 1,last_index+1-n ):
pre=move
move = move.next
# end of for loop, move is the node I want to remove
pre.next = move.next
return head
20. Valid Parentheses
Given a string s
containing just the characters '('
, ')'
, '{'
, '}'
, '['
and ']'
, determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
Example 1:
Input: s = "()"
Output: true
Example 2:
Input: s = "()[]{}"
Output: true
Example 3:
Input: s = "(]"
Output: false
Example 4:
Input: s = "([)]"
Output: false
Example 5:
Input: s = "{[]}"
Output: true
class Solution:
def isValid(self, s: str) -> bool:
if len(s) % 2!=0:
return False
stack_left_brackets=[]
bracket_dict = {')':'(',
'}':'{',
']':'['}
for c in s:
if c in bracket_dict.keys() and len(stack_left_brackets)>0 and stack_left_brackets[-1]==bracket_dict[c]:
stack_left_brackets.pop()
else:
stack_left_brackets.append(c) # step 1
return len(stack_left_brackets)==0
####################################### wrong ########################################
# stack_brackets=[None]
# bracket_dict = {')':'(', '}':'{', ']':'['}
# print("0:",s) # ==> 0: ()
# for c in s:
# print("1:", stack_brackets, ", c:", c) # ==> 1: [None], c: ( ==> 1: [None, '('], c: )
# print( c in bracket_dict.keys() ) # False ==> True
# if c in bracket_dict.keys() and ( bracket_dict[c]!=stack_brackets.pop() ): #==>pop out '('
# print("2:",stack_brackets) # ==> ???
# continue
# else:
# if c in bracket_dict.keys() :
# print(bracket_dict[c])
# stack_brackets.append(c)
# print("3:",stack_brackets) # ==> 3: [None, '('] ==> 3: [None, ')']
# return len(stack_brackets)==1
####################################### wrong ########################################
# OR
# stack_brackets=[None]
# bracket_dict = {')':'(', '}':'{', ']':'['}
# for c in s:
# if c in bracket_dict.keys():
# if bracket_dict[c]!=stack_brackets.pop():
# return False
# else:
# stack_brackets.append(c)
# return len(stack_brackets)==1
21. Merge Two Sorted Lists
Merge two sorted linked lists and return it as a sorted list. The list should be made by splicing together the nodes of the first two lists.
Example 1:
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
Example 2:
Input: l1 = [], l2 = []
Output: []
Example 3:
Input: l1 = [], l2 = [0]
Output: [0]
Constraints:
- The number of nodes in both lists is in the range
[0, 50]
. -100 <= Node.val <= 100
- Both
l1
andl2
are sorted in non-decreasing order.# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: h_merged = move = ListNode(0) # The number of nodes in both lists is in the range [0, 50] while l1 and l2: if l1.val < l2.val: move.next = l1 l1 = l1.next else: move.next = l2 l2 = l2.next move = move.next # l1: 1 -> 2 -> 4 -> None # l2: 1 -> 3 -> 4 -> None # l1: 1 -> 2 4 -> None l1 -> None # ^ | ^ # | V | # l2: 1 3 -> 4 l2 -> None # ^ # | # h_merged: 0 move.next = l1 or l2 return h_merged.next
22. Generate Parentheses
Given n
pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
Example 1:
Input: n = 3
Output: ["((()))","(()())","(())()","()(())","()()()"]
Example 2:
Input: n = 1
Output: ["()"]
Constraints:
1 <= n <= 8
class Solution:
def generateParenthesis(self, n: int) -> List[str]:
parentheses_list = []
# 1 <= n <= 8
def recursiveAppend( s ='', L=0, n=1):
if n==0:
parentheses_list.append( s + ')'*L ) # step 3-4 # s='((()))' ==> [ '((()))', ] ## step 2-8 # recursiveAppend( s+'(', 1, 0) #==> s="(()())" ==> [ '((()))', "(()())", ] #==> s="()(())"
return
recursiveAppend( s+'(', L+1, n-1 ) # step 1 ## step 2-6 ## step 1-10
# recursiveAppend( s+'(', 1, 2 ) # step 1 # ==> s='(' ## recursiveAppend( s+'(', 2, 0) #==> s="(()(" ## recursiveAppend( s+')', 1, 1 ) #==> s="()("
# recursiveAppend( s+'(', 2, 1 ) # step 2 # ==> s='((' ## recursiveAppend( s+')', 2, 0 ) #==> s="()(("
# recursiveAppend( s+'(', 3, 0 ) # step 3 # ==> s='((('
if L >0: # step 2-5 # ==> s='((' ## step 2-7 ## step 1-9 # ==> s='('
recursiveAppend( s+')', L-1, n) # recursiveAppend( s+')', 1, 1) # ==> s="(()" ## recursiveAppend( s+'(', 1, 0) #==> s="(()()" ## recursiveAppend( s+')', 0, 2 ) #==> s="()"
# n = 3
recursiveAppend('', 0, n) # step 0
return parentheses_list
23. Merge k Sorted Lists
Min heap: https://zhuanlan.zhihu.com/p/266665145
You are given an array of k
linked-lists lists
, each linked-list is sorted in ascending order.
Merge all the linked-lists into one sorted linked-list and return it.
Example 1:
Input: lists = [ [1,4,5],[1,3,4],[2,6] ]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked-lists are:
[
1->4->5,
1->3->4,
2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6
Example 2:
Input: lists = []
Output: []
Example 3:
Input: lists = [ [] ]
Output: []
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
import heapq
class Solution:
def mergeKLists(self, lists: List[ListNode]) -> ListNode:
if len(lists) ==0:
return # OR # None
h_merged = move = ListNode(0)
if len(lists) ==1 and lists[0]==None:
move.next = lists[0]
return None
queue=[]
idx=0 # the index of the linked-list(the element) in the lists
for node in lists: # node: lists[i] is sorted in ascending order.
if node != None:
heapq.heappush( queue,
(node.val, idx, node) # since the nodes' value maybe equal, so idx is used
)
idx+=1
# if lists == [ [1,4,5],[1,3,4],[2,6] ]
# print( queue )
#(node.val, idx, node)
# [ (1, 0, ListNode{ val: 1, next: ListNode{ val: 4, next: ListNode{val: 5, next: None} } } ),
# (1, 1, ListNode{ val: 1, next: ListNode{ val: 3, next: ListNode{val: 4, next: None} } } ),
# (2, 2, ListNode{ val: 2, next: ListNode{ val: 6, next: None } } )
# ]
while len(queue) > 0:
# Pop and return the smallest item from the heap by comparing the node.val(if exists same value) then comparing idx
_, idx, move.next = heapq.heappop( queue ) # move.next --> the smallest val and idx of ListNode
move = move.next # move --> the smallest ListNode
if move.next != None:
heapq.heappush( queue,
( move.next.val, idx, move.next ), # e.g. (4, 0, move.next-->[4,5])
)
return h_merged.next
24. Swap Nodes in Pairs
Input: head = [1,2,3,4]
Output: [2,1,4,3]
Example 2:
Input: head = []
Output: []
Example 3:
Input: head = [1]
Output: [1]
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if head == None:
return # OR # None
if head.next == None:
return head
pre = ListNode(None) # pre = self
pre.next = head
head = head.next # pre.next.next
while pre.next != None and pre.next.next !=None :
left = pre.next
right = left.next
pre.next = right
left.next = right.next
right.next = left
pre = left
return head
# pre = ListNode(None) # pre(None)
# # if head = [1,2,3,4] |
# # V
# pre.next = head # None --> 1 --> 2 --> 3 --> 4 --> None
# # ^ ^
# # | |
# # left right
# left = pre.next
# head = right = left.next
# # pre(None) -x-> 1 -x-> 2 -x-> 3 --> 4 --> None # Note x : cut off
# # ^ ^
# # | |
# # left right
# pre.next = right # pre(None) --> 2 --> 3 --> 4 --> None
# left.next = right.next # left(1) --> 3 --> 4 --> None
# right.next = left # right(2) --> 1 --> 3 --> 4 --> None
# pre = left # pre(1) --> 3 --> 4 --> None
# # print(pre)
# # ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}
# # print(right)
# # ListNode{val: 2, next: ListNode{val: 1, next: ListNode{val: 3, next: ListNode{val: 4, next: None}}}}
# # pre left right
# # | | |
# # V V V
# # head(2) --> 1 -x-> 3 -x-> 4 -x-> None
# left = pre.next
# right = left.next
# pre.next = right # pre(1) --> 4 --> None
# left.next = right.next # left(3) --> None
# right.next = left # right(4) --> 3 --> None
# pre = left # pre(3) --> None
# # print(left) # ListNode{val: 3, next: None}
# # print(right) # ListNode{val: 4, next: ListNode{val: 3, next: None}}
# return head
25. Reverse Nodes in k-Group
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes, in the end, should remain as it is.
You may not alter the values in the list's nodes, only nodes themselves may be changed.
Example 1:
Input: head = [1,2,3,4,5], k = 2
Output: [2,1,4,3,5]
Example 2:
Input: head = [1,2,3,4,5], k = 3
Output: [3,2,1,4,5]
Example 3:
Input: head = [1,2,3,4,5], k = 1
Output: [1,2,3,4,5]
Example 4:
Input: head = [1], k = 1
Output: [1]
Constraints:
- The number of nodes in the list is in the range
sz
. 1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
if k ==1:
return head
h_reversed = jump = ListNode(None)
h_reversed.next = left_start = right_end = head # if head(1) --> 2 --> 3 --> 4 --> 5 ,k=3
while True:
count = 0
while right_end != None and count<k:
right_end = right_end.next
count += 1
if count == k: # I can reverse the sub-linked list[left_start, right_end)
cur = left_start # left_start(1) right_end(4)
pre = right_end # || ||
# || ||
for _ in range(k): # if cur(1) -x-> 2 --> 3 --> pre(4) --> 5 --> None, k=3 # Note, x : cut off
cur_next = cur.next # | ^
cur.next = pre # |_______________________|
pre = cur # Now, we can move "pre" one step back by an assignment
cur = cur_next # and move "cur" to the (previous) next node by an assignment
# for next loop
# ————————— pre(1)
# | |
# | V
# cur(2) -x-> 3 --> 4 --> 5 --> None ## Note, x : cut off
# for next loop
# ---> pre(2)
# | |
# | V
# | 1
# | |
# | V
# cur(3) -x-> 4 --> 5 --> None
# end for loop
# pre(3) --> 2 --> left_start(1) --> cur(4) or right_end(4) --> 5 --> None
# h_reversed = jump # ||
# h_reversed.next = head # ||
jump.next = pre # head--> reversed sub-linked list -->next... ||
jump = left_start # the end node for next link(jump.next = pre) ||
left_start = right_end # right_end(4)
else:
return h_reversed.next