LeetCode题集四
简单题
121. 买卖股票的最佳时机
题目:
思路:
先将第一个值默认是最小的价钱,之后依次查找后面的价格,进行对比获取最小价格和最大收益。
解法:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices) < 2:
return 0
res = 0
min_num = prices[0]
for p in prices:
min_num = min(p, min_num)
res = max(p - min_num, res)
return res
122. 买卖股票的最佳时机 II
题目:
思路:
默认第一个值为当前值,当下一个值比上一个小,那么把这个值设置当前值,如果上一个值比当前值大,那么计算可以取得的收益。
解法:
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices) < 2:
return 0
res = 0
now_price = prices[0]
for p in prices:
if p <= now_price:
now_price = p
continue
res += p - now_price
now_price = p
return res
125. 验证回文串
题目:
思路:
先把数组全部大写或者小写,之后去除多余的符号,然后正序和逆序对比
解法:
class Solution:
def isPalindrome(self, s: str) -> bool:
s_new = ""
for i in s.lower():
if 97 <= ord(i) <= 122 or 48 <= ord(i) <= 57:
s_new += i
return s_new == s_new [::-1]
参考了别人的答案,过滤可以用内置函数实现。
class Solution:
def isPalindrome(self, s: str) -> bool:
s_new = list(filter(str.isalnum, s.lower()))
return s_new == s_new [::-1]
136. 只出现一次的数字
题目:
思路:
- 遍历列表使用.
count
方法()查找数量等于1的数(耗时太久);- 设置一个空列表,遍历列表,当数字不在空列表中的时候,添加数字,当存在的时候,删除(使用了额外空间以及效果知识略好于1);
- 使用字典实现。
- 异或:0与任何数异或等于0,相同的数异或为0
解法:
- count实现
class Solution:
def singleNumber(self, nums: List[int]) -> int:
for n in nums:
if nums.count(n) == 1:
return n
- 空列表
class Solution:
def singleNumber(self, nums: List[int]) -> int:
nums_list = []
for n in nums:
if n not in nums_list:
nums_list.append(n)
continue
nums_list.remove(n)
return nums_list[0]
- dict实现
class Solution:
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
dict = {}
for num in nums:
if num in dict:
dict[num] += 1
else:
dict[num] = 1
for key in dict.keys():
if dict[key] == 1:
return key
- 异或
class Solution:
def singleNumber(self, nums: List[int]) -> int:
a = 0
for num in nums:
a = a ^ num
return a
141. 环形链表
题目:
思路:
- 使用一快一慢的指针,当指针相与的时候,说明是存在环的:
- 建立哈希表,路过的路径标记为1,当重复走到标记为1的时候,则是有环的。
解法:
- 快慢指针
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next:
return False
slow = head
fast = head.next
while fast and fast.next:
if slow == fast:
return True
slow = slow.next
fast = fast.next.next
return False
- 哈希表
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next:
return False
hash_dict = {}
node = head.next
while node:
if hash_dict.get(node, 0) != 0:
return True
hash_dict[node] = 1
node = node.next
return False
155. 最小栈
题目:
思路:
使用两个栈实现,一个存放数据的主栈和一个存放当前位置最小值的辅助栈
解法:
class MinStack:
def __init__(self):
"""
initialize your data structure here.
"""
self.stack = []
self.min_stack = [inf]
def push(self, x: int) -> None:
self.stack.append(x)
# 原本是在主栈里找最小值,但是太耗时,更正成与辅助栈的栈顶值相比(所以默认辅助栈需要一个正无穷大值)
self.min_stack.append(min(x, self.min_stack[-1]))
def pop(self) -> None:
self.stack.pop()
self.min_stack.pop()
def top(self) -> int:
return self.stack[-1]
def getMin(self) -> int:
return self.min_stack[-1]
# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()
160. 相交链表
题目:
思路:
1.对比两个链表,将长的链表先next到和短的一样长,然后遍历A和B链表进行每个结点的对比。
2.拼接两个链表,这样长度就是一样的了。然后一一对比,如果有环,最后的结点肯定是相同的。
解法:
- 长链表next到与短链表相同长度
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
# 获取链表的长度
def get_len(L):
n = 0
while L:
n += 1; L = L.next
return n
# 预走的步数
pre_step = get_len(headA) - get_len(headB)
# 判断A长还是B长
if pre_step < 0:
headA, headB = headB, headA
pre_step = abs(pre_step)
# 将长的链表先进行next到和短的一样长
for i in range(pre_step):
headA = headA.next
# 比对结点
while headA and headB:
if headA == headB:
return headA
headA, headB = headA.next, headB.next
return None
- 链表拼接(遍历A+B 和 B + A进行对比)
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
LA, LB = headA, headB
while LA != LB:
LA = LA.next if LA else headB
LB = LB.next if LB else headA
return LA
167. 两数之和 II - 输入有序数组
题目:
思路:
和
1.两数之和
那道题类似,修改下返回值就可以实现。推荐使用dict来实现。
解法:
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
hash_map = {}
for i, num in enumerate(numbers):
another_num = target - num
if another_num in hash_map:
return [hash_map[another_num], i + 1]
hash_map[num] = i + 1
return None
168. Excel表列名称
题目:
思路:
26进制问题,可以整除26取整数和余数,然后用余数和A(65)相加计算得到后面一位的值。
解法:
class Solution:
def convertToTitle(self, n: int) -> str:
res = ""
while n:
n -= 1
n, m = divmod(n, 26)
res = chr(m + 65) + res
return res
169. 多数元素
题目:
思路:
1.排序,中间 + 1的那个数就是最多的
2.参考了大神的答案,摩尔投票法是个很好的选择。
解法:
- 排序
class Solution:
def majorityElement(self, nums: List[int]) -> int:
nums.sort()
return nums[len(nums)//2]
- 摩尔投票法
class Solution(object):
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
major = 0
count = 0
for n in nums:
if count == 0:
major = n
if n == major:
count = count + 1
else:
count = count - 1
return major