leetcode刷题记录

# LeetCode

## Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

``````Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
``````

### 思路分析

#### 方法一

``````class Solution:
def twoSum(self, nums, target):
length = len(nums)  # 计算输入的列表长度
for i in range(length):
for j in range(length):
if nums[i] + nums[j] == target:
return [i, j]
``````

#### 方法二

``````class Solution:
def twoSum(self, nums, target):
arr = {}  # 使用字典存储遍历过的num和对应下标{num:index}
length = len(nums)  # 计算输入的列表长度
for i in range(length):
if (target - nums[i]) in arr:
# 如果target-当前num的差在arr中，则表示已经找到答案，返回结果即可
return [arr[target - nums[i]], i]
# 否则，将该num及其下标存入arr中
arr[nums[i]] = i
``````

## Reverse Integer

Reverse digits of an integer.

``````Example1: x = 123, return 321
Example2: x = -123, return -321
``````

### 思路分析

#### 方法一

``````class Solution:
def reverse(self, x):
# 对x判断为正还是为负
if x < 0:
x = abs(x)
# 先将数字转为字符串，再用反向切片操作(其他语言也都有字符串倒置函数)
return self.isOverFlows(-int(str(x)[::-1]))
else:
return self.isOverFlows(int(str(x)[::-1]))

# 判断x是否在32位有符号数
def isOverFlows(self, x):
if pow(-2, 31) < x < pow(2, 31):
return x
return 0
``````

## Palindrome Number

Determine whether an integer is a palindrome. Do this without extra space.

### 思路分析

#### 方法一

``````class Solution:
def isPalindrome(self, x):
# 将数字转换为字符串
x = str(x)
# 得到字符串的长度
n = len(x)
# 对字符串进行迭代
for i in range(n):
# 判断头和尾是否相等并且头要小于尾
if x[i] != x[n - i - 1] and i < n - i - 1:
return False
return True
``````

## Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings..

['aaa','ab'] ==> a
['aaa'] ==> aaa
[]==> ''

### 思路分析

#### 方法一

``````class Solution:
def longestCommonPrefix(self, strs):
# 判断字符串列表是否为空
if not strs:
return ''
# 计算字符串列表中最短的字符串
min_str = min(strs)
# 计算最短字符串的长度
min_length = len(min_str)
# 初始令最长共同前缀字符串为最短字符串的第一个字符
max_common_str = min_str[:1]
for i in range(min_length):
for str in strs:
# 判断字符串列表中每个字符串的前i+1位是否与最长共同字符串相同
# 不同则判断当前字符串是否为第1个，是则返回空，不是则返回前i位字符串
if str[:i + 1] != max_common_str:
if i == 0:
return ''
return str[:i]
# 当每个字符串前i+1位都与共同前缀字符相同时，判断字符串是否最短字符串相同
# 相同则返回最长共同前缀字符
if min_str == max_common_str:
return max_common_str
# 不相同则返回前i+1+1位字符串(使字符串向后移动一位)
max_common_str = min_str[:i + 1 + 1]
return max_common_str
``````

## Valid Parentheses

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.

### 思路分析

#### 方法一

``````class Solution:
def isValid(self, s):
'''
:param s: str
:return: bool
'''
left_char = '({['
mp = {
')': '(',
']': '[',
'}': '{'
}
# 初始化一个空列表作为栈
stack = []
# 循环遍历字符串
for i in s:
# 如果字符是左括号就入栈
if i in left_char:
stack.append(i)
else:
# 如果也想加上对其他字符串匹配
# if i in mp.keys():
# 栈为空或者传入的右括号不等于栈尾的左括号，即不符合条件
if not stack or mp[i] != stack.pop():
return False
# 判断栈是否为空，为空即成立
if not stack:
return True
return False
``````

## Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

### 思路分析

``````class ListNode:
def __init__(self, x):
self.val = x
self.next = None
``````

#### 方法一

``````class Solution:
def mergeTwoLists(self, l1, l2):
'''
:param l1: ListNode
:param l2: ListNode
:return: ListNode
'''
# 如果l1或l2有一个为空，则返回另一个
if not l1 or not l2:
return l1 or l2
# 比较l1和l2的值的大小
if l1.val < l2.val:
# 将l2递归到l1上
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
# 将l1递归到l2上
l2.next = self.mergeTwoLists(l2.next, l1)
return l2
``````

## Remove Duplicates from Sorted Array

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

Given input array nums = [1,1,2]
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length

### 思路分析

``````len(set(nums))
``````

#### 方法一

``````class Solution:
def removeDuplicates(self, nums):
'''
:param nums: list[int]
:return:int
'''
# 如果数组为空，则返回0
if not nums:
return 0
new_length = 0
length = len(nums)
# 从1到n-1开始循环遍历
for i in range(1, length):
# 如果i不等于nums[now_length](其实是i-1)
if nums[i] != nums[new_length]:
new_length += 1
nums[new_length] = nums[i]
return new_length + 1
``````

## Remove Element

Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Given input array nums = [3,2,2,3], val = 3
Your function should return length = 2, with the first two elements of nums being 2

### 思路分析

#### 方法一

``````class Solution:
def removeElement(self, nums, val):
length = 0
for i in range(len(nums)):
if nums[i] != val:
nums[length] = nums[i]
length += 1
return length, nums
``````

## Search Insert Position

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.

``````Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
``````

### 思路分析

#### 方法一

``````class Solution:
def removeElement(self, nums, val):
length = 0
for i in range(len(nums)):
if nums[i] != val:
nums[length] = nums[i]
length += 1
return length, nums
``````

## Maximum Subarray

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

``````given the array [-2,1,-3,4,-1,2,1,-5,4],
the contiguous subarray [4,-1,2,1] has the largest sum = 6
``````

### 思路分析

#### 方法一

``````class Solution:
def maxSubArray(self, nums):
"""
计算列表中连续子数组的最大和
:param nums: list[int]
:return: int
"""
start = 0
stop = 0
length = len(nums)
if length == 1:
return sum(nums)
largest_sum = nums[0]
for i in range(0, length):
max_sum = nums[0]
for j in range(i, length):
ij_sum = sum(nums[i: j + 1])
if ij_sum > max_sum:
stop = j
max_sum = ij_sum
if max_sum > largest_sum:
start = i
largest_sum = max_sum
return largest_sum
``````

#### 方法二

``````class Solution:
def maxSubArray(self, nums):
"""
计算列表中连续子数组的最大和
:param nums: list[int]
:return: int
"""
if not nums:
return 0
cur_sum = nums[0]
max_sum = nums[0]
for i in nums[1:]:
# 计算当前的和与i相加之后的和比较的最大值
cur_sum = max(i, cur_sum + i)
# 计算当前和与最大和比较的最大值
max_sum = max(max_sum, cur_sum)
return max_sum
``````

## Count and Say

The count-and-say sequence is the sequence of integers with the first five terms as following:

``````1.     1
2.     11
3.     21
4.     1211
5.     111221
``````

1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.
Given an integer n, generate the nth term of the count-and-say sequence.

``````Input: 1
Output: "1"

Input: 4
Output: "1211"
``````

### 思路分析

#### 方法一

``````class Solution:
def countAndSay(self, n):
"""

:param n: int
:return: str
"""
if n == 0:
return ''
if n == 1:
return '1'
# 得到上一次的结果
n1_str = self.countAndSay(n - 1)
# 末尾字符赋值为上一次结果的第一个字符
last = n1_str[0]
cnt = 1
n_str = ''
# 从索引1开始迭代
for i in range(1, len(n1_str)):
# 如果当前元素等于初始末尾字符(上一次结果的第一个字符)
if n1_str[i] == last:
cnt += 1
else:
n_str = n_str + str(cnt)
n_str = n_str + last
# 将数量重置为1
cnt = 1
last = n1_str[i]
n_str = n_str + str(cnt)
n_str = n_str + last
return n_str
``````

## Count and Say

Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.
If the last word does not exist, return 0.
Note: A word is defined as a character sequence consists of non-space characters only.

``````Given s = "Hello World",
return 5.
``````

### 思路分析

#### 方法一

``````class Solution:
def lengthOfLastWord(self, s):
"""
返回字符串中最后一个单词的长度
:param s: str
:return: int
"""
# 先去掉首尾的空格
# 在按空格切割字符串转换为列表
# 取列表最后一个元素计算长度
return len(s.strip().split(' ')[-1])
``````

Given two binary strings, return their sum (also a binary string).

``````a = "11"
b = "1"
Return "100".
``````

### 思路分析

#### 方法一

``````class Solution:
"""
二进制加法
:param a:
:param b:
:return:
"""
a, b = int(a, 2), int(b, 2)
# 由于bin()方法转为的二进制会有0b前缀，所有我们需要用字符串切到2之后
return bin(a+b)[2:]
``````

## Sqrt(x)

Implement int sqrt(int x).
Compute and return the square root of x.

### 思路分析

#### 方法一

``````class Solution:
def mySqrt(self, x):
"""
计算平方根
:param x: int
:return: int
"""
import math
return int(math.sqrt(x))
``````

#### 方法一

``````class Solution:
def mySqrt(self, x):
"""
计算平方根
:param x: int
:return: int
"""
return int(x ** 0.5)
``````

## Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.

### 思路分析

#### 方法一

``````class Solution:
def climbStairs(self, n):
"""

:param n: int
:return: int
"""
a = b = 1
for i in range(n):
a, b = b, a + b
return a
``````

## Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

``````Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.
``````

### 思路分析

#### 方法一

``````class Solution:
"""
有序单链表去重
:return: ListNode
"""
# 如果当前结点不为空
while current:
# 如果当前结点的下一个结点存在
# 并且当前结点的值等于下一个结点的值
while current.next and current.val == current.next.val:
# 当前结点的下一个结点等于当前结点的下下个结点
current.next = current.next.next
# 再降当前结点的下一个结点赋值给当前结点
current = current.next
# 返回已经去重的单链表
``````

## Merge Sorted Array

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.

### 思路分析

#### 方法一

``````class Solution:
def merge(self, nums1, m, nums2, n):
"""
将列表nums2合并到nums1上
:param nums1: list[int]
:param m: int
:param nums2: list[int]
:param n: int
:return: void
"""
while m > 0 and n > 0:
if nums1[m - 1] >= nums2[n - 1]:
nums1[m + n - 1] = nums1[m - 1]
m -= 1
else:
nums1[m - n - 1] = nums2[n - 1]
n -= 1
if n > 0:
nums1[:n] = nums2[:n]
``````

## Same Tree

Given two binary trees, write a function to check if they are equal or not.
Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

### 思路分析

#### 方法一

``````class Solution:
def isSameTree(self, p, q):
"""
判断两个二叉树是否相同（值相同即相同）
:param p: TreeNode
:param q: TreeNode
:return: bool
"""
# 如果p和q都不为空
if p and p:
# 当前结点的值是否相等
if p.val == q.val:
# 判断当前结点的下一个左右结点是否相等
return self.isSameTree(q.left, p.left) \
and self.isSameTree(q.right, p.right)
# 如果p和q均为空
if not p and not q:
return True
return False
``````

## Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

``````For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

1
/ \
2   2
/ \ / \
3  4 4  3
But the following [1,2,2,null,3,null,3] is not:
1
/ \
2   2
\   \
3    3
``````

### 思路分析

#### 方法一

``````class Solution:
def isSymmetric(self, root):
"""
判断一颗树是否是镜像树
:param root: TreeNode
:return: bool
"""
return self.isMirror(root, root)

def isMirror(self, tree_node1, tree_node2):
"""
判断两棵树是否镜像
:param tree_node1: TreeNode
:param tree_node2: TreeNode
:return: bool
"""
# 如果两个叶子结点均为空
if not tree_node1 and not tree_node2:
return True
# 如果只有一个叶子结点为空
if not tree_node1 or not tree_node2:
return False
# 当前叶子结点的值相等，并且一颗树的左子树等于另一颗树的右子树
return (tree_node1.val == tree_node2.val) \
and self.isMirror(tree_node1.right, tree_node2.left) \
and self.isMirror(tree_node1.left, tree_node2.right)
``````

## Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.
The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

### 思路分析

#### 方法一

``````class Solution:
def maxDepth(self, root):
"""
计算树的最大深度
:param root: TreeNode
:return: int
"""
# 如果根结点为空返回0
if not root:
return 0
# 计算左右子树的中的最大深度，加上根节点
return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
``````