leetcode热题系列章节11

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 0
    d = {}
    p1,p2 = -1,0
    max_len = 0
    while p1 < len(s) and p2 < len(s):
        if s[p2] in d:
            p1 = max(p1, d[s[p2]])
        d[s[p2]] = p2
        max_len = max(p2 - p1, max_len)
        p2 += 1
    return max_len

在这里插入图片描述

#coding:utf-8
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param s string字符串 
# @return int整型
#
class Solution:
    def lengthOfLongestSubstring(self , s ):
        # write code here
        dic = {} # 存储当前字符上次出现的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 += 1
            else:
                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, None
    for 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] = hc
            break

    if lc is not None:
        for i in range(len(num_list) - 1, -1, -1):
            if num_list[i] == hc:
                num_list[i] = lc
                break

    return 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 = [""] * k
        self.max_length = k
        self.start = -1
        self.end = -1
 
    def 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 = 0
            self.end = (self.end + 1) % self.max_length
            self.queue[self.end] = value
            return True
        else:
            return False
        
        
 
    def 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 element
                self.start, self.end = -1, -1
                # self.end = -1
            else:
                self.start = (self.start + 1) % self.max_length
            return True
        else:
            return False
        
 
    def 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 == -1
 
    def 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 = val
        self.left = left
        self.right = right
"""
class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        if not root:return 
        # 当一个中间节点
        head = Node(-1, None, None)
        # 记录为先前节点,找到下一个节点才能串起来
        prev = head
        # 中序遍历的非递归
        stack = []
        p = root
        while p or stack:
            while p:
                stack.append(p)
                p = p.left
            p = stack.pop()
            # 改变左右方向
            prev.right = p
            p.left = prev
            # 改变先前节点
            prev = p
            p = p.right
        # 将head 删掉   
        head.right.left = prev
        prev.right = head.right
        return head.right





写法二:递归

"""
# Definition for a Node.
class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.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 prev
            if not root:
                return 
            inorder(root.left)
            prev.right = root
            root.left = prev
            prev = prev.right
            inorder(root.right)

        inorder(root)
        # 将head 删掉   
        head.right.left = prev
        prev.right = head.right
        return 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 = 0
        while i < len(nums) - 1:
            if nums[i] > nums[i+1]:
                return nums[i+1]
            i += 1
        return 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]

面试题 17.24. 最大子矩阵

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值