378. 有序矩阵中第K小的元素
给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第k小的元素。
请注意,它是排序后的第k小元素,而不是第k个元素。
示例:
matrix = [
[ 1, 5, 9],
[10, 11, 13],
[12, 13, 15]
],
k = 8,
返回 13。
说明:
你可以假设 k 的值永远是有效的, 1 ≤ k ≤ n2 。
class Solution:def kthSmallest(self, matrix: List[List[int]], k: int) -> int:list_matrix = []for i in range(len(matrix)):list_matrix += matrix[i]heapq.heapify(list_matrix)return [heapq.heappop(list_matrix) for _ in range(k)][-1]
剑指 Offer 48. 最长不含重复字符的子字符串
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
提示:
s.length <= 40000
def longest_sub_str_1(s):if not s or len(s) == 0:return 0d = {}p1,p2 = -1,0max_len = 0while p1 < len(s) and p2 < len(s):if s[p2] in d:p1 = max(p1, d[s[p2]])d[s[p2]] = p2max_len = max(p2 - p1, max_len)p2 += 1return max_len
#coding:utf-8
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param s string字符串
# @return int整型
#
class Solution:def lengthOfLongestSubstring(self , s ):# write code heredic = {} # 存储当前字符上次出现的idx max_n, last_max = 0, 0 for j in range(len(s)):i = dic.get(s[j], -1) # 上次该字符出现的位置if j - i > last_max: # 如果出现 dvdf 这种f第一次出现的情况,需要判断一下是否是大于前一个最长串last_max += 1else:last_max = j - i max_n = max(max_n, last_max)dic[s[j]] = j return max_n
670. 最大交换
一、题目
给定一个非负整数,你 至多 可以交换一次数字中的任意两位。返回你能得到的最大值。
二、示例
2.1> 示例 1 :
【输入】 2736
【输出】 7236
【解释】 交换数字2和数字7。
2.2> 示例 2 :
【输入】 9973
【输出】 9973
【解释】 不需要交换。
def maximum_swap(num):num_list = list(str(num))sorted_num_list = sorted(num_list, reverse=True)lc, hc = None, Nonefor i in range(len(num_list)):if num_list[i] != sorted_num_list[i]:lc = num_list[i]hc = sorted_num_list[i]num_list[i] = hcbreakif lc is not None:for i in range(len(num_list) - 1, -1, -1):if num_list[i] == hc:num_list[i] = lcbreakreturn int(''.join(num_list))
622. 设计循环队列
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:
MyCircularQueue(k): 构造器,设置队列长度为 k 。
Front: 从队首获取元素。如果队列为空,返回 -1 。
Rear: 获取队尾元素。如果队列为空,返回 -1 。
enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
isEmpty(): 检查循环队列是否为空。
isFull(): 检查循环队列是否已满。
示例:
MyCircularQueue circularQueue = new MycircularQueue(3); // 设置长度为3
circularQueue.enQueue(1); // 返回true
circularQueue.enQueue(2); // 返回true
circularQueue.enQueue(3); // 返回true
circularQueue.enQueue(4); // 返回false,队列已满
circularQueue.Rear(); // 返回3
circularQueue.isFull(); // 返回true
circularQueue.deQueue(); // 返回true
circularQueue.enQueue(4); // 返回true
circularQueue.Rear(); // 返回4
思路:
双指针法,start指向目前队列的头,end指向目前队列的尾,两者初始值都为-1,
插入元素时,如果是第一个元素,那么start end 都变成 0
如果不是第一个元素,队尾延长,end + 1,注意是循环的队列所以需要%最大长度
如果队列已经满了,就返回False
删除元素时,如果是最后一个元素,那么start end 都变成-1
如果不是最后一个元素,队头出队,start + 1, 同样注意循环
如果队列是空的,就返回Flase
返回队头,如果有队头,直接输出start指向的元素;否则按题目要求输出-1
返回队尾,如果有队尾,直接输出end指向的元素;否则按题目要求输出-1
检查是否Full,如果end的下一位是start,就代表已经full
检查是否Empty,如果start 和end 都是-1,就代表已经empty
class MyCircularQueue(object):def __init__(self, k):"""Initialize your data structure here. Set the size of the queue to be k.:type k: int"""self.queue = [""] * kself.max_length = kself.start = -1self.end = -1def enQueue(self, value):"""Insert an element into the circular queue. Return true if the operation is successful.:type value: int:rtype: bool"""if not self.isFull():if self.start == -1:self.start = 0self.end = (self.end + 1) % self.max_lengthself.queue[self.end] = valuereturn Trueelse:return Falsedef deQueue(self):"""Delete an element from the circular queue. Return true if the operation is successful.:rtype: bool"""if not self.isEmpty(): if self.start == self.end: # the last elementself.start, self.end = -1, -1# self.end = -1else:self.start = (self.start + 1) % self.max_lengthreturn Trueelse:return Falsedef Front(self):"""Get the front item from the queue.:rtype: int"""return -1 if self.isEmpty() else self.queue[self.start]def Rear(self):"""Get the last item from the queue.:rtype: int"""return -1 if self.isEmpty() else self.queue[self.end]def isEmpty(self):"""Checks whether the circular queue is empty or not.:rtype: bool"""return self.start == -1 and self.end == -1def isFull(self):"""Checks whether the circular queue is full or not.:rtype: bool"""return (self.end + 1) % self.max_length == self.start# Your MyCircularQueue object will be instantiated and called as such:
# obj = MyCircularQueue(k)
# param_1 = obj.enQueue(value)
# param_2 = obj.deQueue()
# param_3 = obj.Front()
# param_4 = obj.Rear()
# param_5 = obj.isEmpty()
# param_6 = obj.isFull()
426. 将二叉搜索树转化为排序的双向链表
将一个二叉搜索树就地转化为一个已排序的双向循环链表。可以将左右孩子指针作为双向循环链表的前驱和后继指针。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
写法一:用栈(非递归)
"""
# Definition for a Node.
class Node:def __init__(self, val, left=None, right=None):self.val = valself.left = leftself.right = right
"""
class Solution:def treeToDoublyList(self, root: 'Node') -> 'Node':if not root:return # 当一个中间节点head = Node(-1, None, None)# 记录为先前节点,找到下一个节点才能串起来prev = head# 中序遍历的非递归stack = []p = rootwhile p or stack:while p:stack.append(p)p = p.leftp = stack.pop()# 改变左右方向prev.right = pp.left = prev# 改变先前节点prev = pp = p.right# 将head 删掉 head.right.left = prevprev.right = head.rightreturn head.right写法二:递归"""
# Definition for a Node.
class Node:def __init__(self, val, left=None, right=None):self.val = valself.left = leftself.right = right
"""
class Solution:def treeToDoublyList(self, root: 'Node') -> 'Node':if not root:return # 当一个中间节点head = Node(-1, None, None)# 记录为先前节点,找到下一个节点才能串起来prev = head# 中序遍历的递归def inorder(root):nonlocal previf not root:return inorder(root.left)prev.right = rootroot.left = prevprev = prev.rightinorder(root.right)inorder(root)# 将head 删掉 head.right.left = prevprev.right = head.rightreturn head.right
154. 寻找旋转排序数组中的最小值 II
已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,4,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,4]
若旋转 7 次,则可以得到 [0,1,4,4,5,6,7]
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。
给你一个可能存在 重复 元素值的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
示例 1:
输入:nums = [1,3,5]
输出:1
1
2
示例 2:
输入:nums = [2,2,2,0,1]
输出:0
1
2
提示:
n == nums.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums 原来是一个升序排序的数组,并进行了 1 至 n 次旋转
class Solution:def findMin(self, nums: List[int]) -> int:i = 0while i < len(nums) - 1:if nums[i] > nums[i+1]:return nums[i+1]i += 1return nums[0]
260. 只出现一次的数字 III
题目描述
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。找出只出现一次的那两个元素。
示例:
输入: [1,2,1,3,2,5]
输出: [3,5]
注意:
结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。
你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
from collections import Counter
class Solution:def singleNumber(self, nums: int) -> List[int]:hashmap = Counter(nums)return [x for x in hashmap if hashmap[x] == 1]