【leetcode】跟着leetcode学算法 - day01

声明

leetcode专栏题目来自leetcode,文章仅是对题目的分析讲解,如有问题请联系本人说明情况,本人核实后于15个工作日内修改

1. 两数之和

通常一进来两数之后我们能够想到的思路就是遍历。两层循环遍历时间复杂度的是ON的平方。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        # 遍历寻找解决方案这里由于题目说他只有一个有效答案,所以直接不断遍历。
        # 时间复杂度的是ON的平方。
        for i in range(len(nums)): 
            for j in range(i + 1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

在这里插入图片描述

这样不好,所以我们试着去优化它。

哈希表优化

首先简单了解一下哈希表

1. 基本概念

1.1 哈希表(Hash Table)

哈希表是一种数据结构,通过散列函数将键值映射到对应的桶或槽中,以实现快速的数据查找。
在这里插入图片描述

(图片来自百度百科)

1.2 散列函数(Hash Function)

散列函数是将输入(键)转换为固定大小的整数值(哈希值)的函数。这个整数值用作哈希表中的索引。(用于构建哈希表的映射函数)

1.3 哈希碰撞(Hash Collision)

当两个不同的键通过散列函数得到相同的哈希值时,就会发生哈希碰撞。(其实就是放入值的时候位置上已经有人了,所以不能放了)

然后我们来解题
python3里面哈希表就可以用字典来实现

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            # 这样的话我遍历到当前位置的元素的时候,我看一下和相减的这个元素在不在这个
            if target - num in hashtable:
                return [hashtable[target - num], i]
                pass
            hashtable[num] = i
        return []
##########################################
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, num in enumerate(nums):
            if target - num in hashtable:
                return [hashtable[target - num], i]
            hashtable[nums[i]] = i
        return []

作者:力扣官方题解
链接:https://leetcode.cn/problems/two-sum/solutions/434597/liang-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述

其实就是用字典简化,优化到线性级别(on是因为遍历一遍就能得到结果),本质上是从都用遍历转换到字典的存在操作
在这里插入图片描述


2. 两数相加

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        
        print("l1", l1)
        my_str_1 = ""
        my_str_2 = ""

        while l1:
            my_str_1 += str(l1.val)
            l1 = l1.next        
        while l2:
            my_str_2 += str(l2.val)
            l2 = l2.next
        
        print("my_str_1", my_str_1)
        print("my_str_2", my_str_2)

        # 逆序+求和
        my_int_3 = int(my_str_1[::-1]) + int(my_str_2[::-1])
        print("my_int_3", my_int_3)

        # 引入链表l3
        l3 = ListNode()
        need_to_return_head = l3

        # 把整数my_int_3拆分成链表
        my_str_3 = str(my_int_3)[::-1]
        for i in range(len(my_str_3)):
            l3.val = int(my_str_3[i])
            if i != len(my_str_3) - 1:
                l3.next = ListNode()
                l3 = l3.next

        return need_to_return_head

简单的按照求和的思路,直接拿出来用加法求,然后丢回到链表里面就好
时间复杂度虽然不错,但是有没有更加巧妙的办法呢
在这里插入图片描述

我们来看一个O(max(m,n))的算法

在这里插入图片描述

可以看到前面为什么不用链表直接操作,主要是这里还要考虑进位,
对于当前值来说就是直接两个数+进位即可(参考数电加法器),另外进位更新为这样的值,两个链表扫描一遍就可以完成要求。还要考虑两个链表都遍历结束后如果进位还是>0的,需要结果里面再增加一个节点放进位

在这里插入图片描述

参考文献

https://baike.baidu.com/item/%E5%93%88%E5%B8%8C%E8%A1%A8/5981869?fr=ge_ala

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_千思_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值