Leetcode刷题系列(1)

1.两数之和

https://leetcode-cn.com/problems/two-sum/

原题

给定一个整数数组 nums 和一个整数目标值 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]

提示:

  • 2 <= nums.length <= 10^3
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9
  • 只会存在一个有效答案

标签
数组 哈希表

解答

解题思路

暴力法:两次for循环,时间复杂度 O ( n 2 ) O(n^2) O(n2), 空间复杂度 O ( 1 ) O(1) O(1)
利用哈希表:哈希表查询时间复杂度 O ( 1 ) O(1) O(1),总的时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n), 达到了空间换时间的效果

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i in range(len(nums)):
            if target-nums[i] not in hashtable:
                hashtable[nums[i]] = i
            else:
                return [hashtable[target-nums[i]], i]
        return None

237.删除链表中的节点

https://leetcode-cn.com/problems/delete-node-in-a-linked-list/

原题

请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点

现有一个链表 – head = [4,5,1,9],它可以表示为:

示例 1:

输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

示例 2:

输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

提示:

  • 链表至少包含两个节点。
  • 链表中所有节点的值都是唯一的。
  • 给定的节点为非末尾节点并且一定是链表中的一个有效节点。
  • 不要从你的函数中返回任何结果。

标签
链表

解答

虽然我们不能delete这个node A,但可以用后面的node B把这个node覆盖掉,然后用它的下下个地址node C来作为node A的下一个地址。我们干掉的其实不是这个node A,而是它的下一个node B,我们本想杀掉的node正披着它的下一个node的外衣活着

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        node.val = node.next.val
        node.next = node.next.next

复杂度分析

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

104.二叉树的最大深度

https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/

原题

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回它的最大深度 3 。

标签
深度优先搜索 递归

解答

解题思路

方法一:深度优先遍历,利用递归,二叉树的最大深度为1+其左子树和右子树深度中最大者

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        else:
            return 1+max(self.maxDepth(root.left),self.maxDepth(root.right))

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(height),树的高度,最坏情况O(n)

方法二:广度优先遍历,每一次遍历完一层深度加1

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root:
            return 0
        queue = collections.deque([root])
        depth = 0
        while queue:
            n = len(queue)
            for i in range(n):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
            depth += 1
        return depth

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(width),树的宽度,最坏情况O(n)

344.反转字符串

https://leetcode-cn.com/problems/reverse-string/

原题

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须 原地修改输入数组 、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

标签
双指针 字符串

解答

解题思路

方法一:分奇数和偶数情况,把关于中点对称的元素互相交换即可

方法二:也可以使用双指针,一个指针从最左往右移动,一个指针从最右往左移动,当相遇或交错位置时停止

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        n = len(s)
        if n % 2 == 1:
            for i in range(int((n-1)/2)):
                s[i],s[n-1-i] = s[n-1-i],s[i]
        else:
            for i in range(int(n/2)):
                s[i],s[n-1-i] = s[n-1-i],s[i]

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

108.将有序数组转换为二叉搜索树

https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/

原题

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例 1:

输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
<img alt="" src="https://assets.leetcode.com/uploads/2021/02/18/btree2.jpg" style="width: 302px; height: 222px;" />

示例 2:

输入:nums = [1,3]
输出:[3,1]
解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示:

  • 1 <= nums.length <= 10^4
  • -10^4 <= nums[i] <= 10^4
  • nums严格递增 顺序排列

标签
深度优先搜索

解答

解题思路

已经升序好的数组要做成一颗平衡的二叉搜索树,关键在于要把排序在中点的中位数作为根节点,然后小于中位数的作为左子树,大于中位数的作为右子树,对于这两颗子树也要以此规律找根节点

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        n = len(nums)
        def make_tree(start_index,end_index):
            if start_index > end_index:
                return None
            else:
                mid_index = (end_index+start_index)//2
                this_tree_root = TreeNode(nums[mid_index])
                this_tree_root.left = make_tree(start_index,mid_index-1)
                this_tree_root.right = make_tree(mid_index+1,end_index)
            return this_tree_root
        return make_tree(0,n-1)

复杂度分析

时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组的长度。每个数字只访问一次

空间复杂度: O ( log ⁡ n ) O(\log n) O(logn),其中 n n n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O ( log ⁡ n ) O(\log n) O(logn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值