zoukankan      html  css  js  c++  java
  • 【刷题】LeetCode刷刷刷 — 2021-05-30(1)

    一、两数之和

    题目描述

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。
    
    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
    
    你可以按任意顺序返回答案。
    

    示例

    示例 1:
    输入:nums = [2,7,11,15], target = 9
    输出:[0,1]
    解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
    
    示例 2:
    输入:nums = [3,2,4], target = 6
    输出:[1,2]
    
    示例 3:
    输入:nums = [3,3], target = 6
    输出:[0,1]
    

    解题

    class Solution(object):
        def twoSum(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: List[int]
            """
            hash_dict = {}
            for i, num in enumerate(nums):
                if target - num in hash_dict:
                    return [i, hash_dict[target - num]]
                else:
                    hash_dict[num] = i
            return []
    

    思路:

    • 建一个字典。
    • 使用enumerate方法for循环数组,可以循环出数组的下标、元素。
    • 在for循环中,判断元素是否在字典的key中,当字典key里出现target-num,说明当前的num即为另一个加数。
      如果不存在,那么就放到dict里,key是元素,value是下标。
    • 此时,取出当前for循环的i,和另一个加数在dict里的value,组成数组返回。

    二、有效的括号

    题目描述

    给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
    
    有效字符串需满足:
    
    左括号必须用相同类型的右括号闭合。
    左括号必须以正确的顺序闭合。
    

    示例

    示例 1:
    
    输入:s = "()"
    输出:true
    示例 2:
    
    输入:s = "()[]{}"
    输出:true
    示例 3:
    
    输入:s = "(]"
    输出:false
    示例 4:
    
    输入:s = "([)]"
    输出:false
    示例 5:
    
    输入:s = "{[]}"
    输出:true
    

    解题

    class Solution:
        def isValid(self, s: str) -> bool:
            if len(s) % 2 == 1:
                return False
            pairs_dict = {
                ")": "(",
                "]": "[",
                "}": "{"
            }
            stack_list = []
            for ch in s:
                if stack_list and ch in pairs_dict:
                    if stack_list[-1] == pairs_dict[ch]:
                        stack_list.pop()
                    else:
                        return False
                else:
                    stack_list.append(ch)
            return not stack_list
    

    解题思路:利用栈的实现思路。

    • for循环字符串
    • 前面的元素 先放进列表
    • 当列表不为空,而且最后面的元素存在 dict的key里,说明可以组成一对括号,就把元素剔除。
    • for循环结束,列表为空说明全部都可以组成括号。

    比如测试输入"{()[()]}",列表里的过程是这样的:

    列表的内容: ['{']
    列表的内容: ['{', '(']
    列表的内容: ['{']
    列表的内容: ['{', '[']
    列表的内容: ['{', '[', '(']
    列表的内容: ['{', '[']
    列表的内容: ['{']
    列表的内容: []
    

    这也是为什么在上面字典里存放的k-v,是")": "("而不是"(": ")",因为判断后面的元素是用的字段里的key,
    所以右括号放在了前面。

    三、二分查找

    题目描述

    给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
    

    示例

    示例 1:
    
    输入: nums = [-1,0,3,5,9,12], target = 9
    输出: 4
    解释: 9 出现在 nums 中并且下标为 4
    示例 2:
    
    输入: nums = [-1,0,3,5,9,12], target = 2
    输出: -1
    解释: 2 不存在 nums 中因此返回 -1
    

    解题

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            left = 0
            right = len(nums) - 1
    
            while left <= right:
                mid = left + (right - left) // 2
                if nums[mid] == target:
                    return mid
                if target < nums[mid]:
                    right = mid - 1
                else:
                    left = mid + 1
            return -1
    

    二分查找:

    • 初始化左、右两个指针,分别为left=0right=len(nums) - 1
    • while循环,当left<right,进行二分计算,找到中间值mid=left + (right-left) // 2
    • 在每次的循环里,用计算出来的mid与目标值target进行比较,三种情况:
    1. mid == target,说明找到了,返回mid
    2. mid > target,那么左指针left不用动,右指针right = mid-1
    3. mid < target, 那么右指针right不用动,左指针left = mid+1

    上述为列表中顺序从小到大。

    如果列表是从大到小,变动点在于mid与target的大小判断后,
    左右指针的移动情况:

    1. mid == target,说明找到了,返回mid
    2. mid > target,那么右指针right不用动,左指针left = mid+1
    3. mid < target,那么左指针left不用动,右指针right = mid-1

    四、环形链表

    题目描述

    给定一个链表,判断链表中是否有环。
    
    如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 
    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 
    如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
    
    如果链表中存在环,则返回 true 。 否则,返回 false 。
    

    示例

    输入:head = [3,2,0,-4], pos = 1
    输出:true
    解释:链表中有一个环,其尾部连接到第二个节点。
    

    解题

    # 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:
            seen = set()
            while head:
                if head in seen:
                    return True
                seen.add(head)
                head = head.next
            return False
    

    从简单角度看,可以遍历所有的结点,判断这个结点之前是否访问过。

    使用哈希表存放已经访问过的结点。在python里,dict()和set()都是基于哈希表的数据结构。

    • 创建set()
    • while循环
    • 每次循环里,判断当前结点是否在set()里。如果存在,返回True;
    • 如果不存在,就把当前结点add增加到set()里,然后当前指针指向下一个结点head = head.next

    五、用栈实现队列

    题目描述

    请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
    
    实现 MyQueue 类:
    
    void push(int x) 将元素 x 推到队列的末尾
    int pop() 从队列的开头移除并返回元素
    int peek() 返回队列开头的元素
    boolean empty() 如果队列为空,返回 true ;否则,返回 false
    
    说明:
    
    你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
    你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
    

    示例

    输入:
    ["MyQueue", "push", "push", "peek", "pop", "empty"]
    [[], [1], [2], [], [], []]
    输出:
    [null, null, null, 1, 1, false]
    
    解释:
    MyQueue myQueue = new MyQueue();
    myQueue.push(1); // queue is: [1]
    myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
    myQueue.peek(); // return 1
    myQueue.pop(); // return 1, queue is [2]
    myQueue.empty(); // return false
    

    解题

    from collections import deque
    
    class MyQueue:
    
        def __init__(self):
            """
            Initialize your data structure here.
            """
            self.deque_nums = deque([])
    
    
        def push(self, x: int) -> None:
            """
            Push element x to the back of queue.
            """
            self.deque_nums.append(x)
    
    
        def pop(self) -> int:
            """
            Removes the element from in front of queue and returns that element.
            """
            return self.deque_nums.popleft()
    
    
        def peek(self) -> int:
            """
            Get the front element.
            """
            return self.deque_nums[0]
    
    
        def empty(self) -> bool:
            """
            Returns whether the queue is empty.
            """
            if len(self.deque_nums) == 0:
                return True
            else:
                return False
    
    
    # Your MyQueue object will be instantiated and called as such:
    # obj = MyQueue()
    # obj.push(x)
    # param_2 = obj.pop()
    # param_3 = obj.peek()
    # param_4 = obj.empty()
    

    这里使用的是python中的collections库,其中deque方法实现了双端队列,以前在博客有过相关整理。

    deque除了实现list的append()pop()外,还提供了appendleft()popleft()
    这样的话我们可以很方便的向着列表的另一头,进行添加和移除操作了

    这里重点就是在于pop方法的实现,队列是要保证先进先出的。比如在列表里[1,2,3,4],那么
    出队的时候,顺序应该也是从前到后一次,所以要求每次出队操作是删除列表第一个元素,所以用
    deque_nums.popleft()

    --不要用肉体的勤奋,去掩盖思考的懒惰--
  • 相关阅读:
    delphi10.3.1不支持.net 5
    FIREDAC返回多结果集
    咏南中间件多种部署方式
    ISAPI多进程设置
    咏南ISAPI中间件
    datasnap isapi程序iis设置
    mormot支持TCP/IP
    咏南中间件支持JWT TOKEN
    基于Token的身份认证 与 基于服务器的身份认证
    delphi开源JWT
  • 原文地址:https://www.cnblogs.com/pingguo-softwaretesting/p/14828801.html
Copyright © 2011-2022 走看看