一起来刷leetcode——第一天 2020/10/28

刷题网站 :https://leetcode-cn.com/
github地址: https://github.com/zhe8300975/myleetcode

整体总结

简单难度 383、387、389
中等难度 2
本次刷题 总结 以下4点

  1. ascii码 可以简化 char类型的运算复杂度
  2. 统计的次数的时候可以借助map 做到空间换时间
  3. char 加减法这种套路 有印象 以后说不定可以发散下
  4. 边界条件 要重视
    总的来说 对应重新开始刷题的你我来说很合适的 长期的业务开发 会让我们基础数据类型的操作变得生疏 这几道题既可以熟悉基础语法 也可以熟悉基本数据类型 不错不错 哈哈

LeetCode 383

题目 —— 赎金信

给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成,返回 true ;否则返回 false。

(题目说明:为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思。杂志字符串中的每个字符只能在赎金信字符串中使用一次。)

注意:

你可以假设两个字符串均只含有小写字母。

canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true

思路

首先题干中可以得到两个点:

  • ransom里面的字符由magazine里面的字符组成
  • magazine里面的字符只能用到一遍

所以可以得出

  • magazine里面的字符需要被记录
  • magazine里面的字符出现的次数需要被被记录

PS :看题可以猜的到 时间复杂度应该O(n)就够用 为什么是O(n)
正常我们应该遍历记录magazine (O(n) n是magazine的长度)
然后遍历ransom一遍对比magazine中的数据 (O(m) m是ransom长度)
整体时间复杂度 O(n+m) & m < n ----> O(2n) -> O(n)

综上 我很容易想到需要用一个Map记录magazine

key-出现的字符
value-字符出现的次数

解题

下面是就开始敲代码了
下面是第一版代码
file

通过 然而 平台提示的是运行速度和内存使用 都是下游水平的由此产生自我怀疑

首先想到的是的思路是不是不对的 ——看起来思路上应该没有问题

那就是代码上看能不能有所优化 —— 使用map的containKey 的话 会调用两次map 所以优化直接判断是不是为null可以做到一次
下面是代码

file

通过 然而 平台提示的是运行速度和内存使用 还是不行 比较是开始刷题 我觉得可以看看答案了

差异点 —— 官方答案中 利用字符的ascii编码 将hashmap退化成程度为26的数组 减少了hashmap 哈希的过程,内存上直接也限制了26 * int (int=4*8位)的数组大小长度
效率和 内存上 都有了显著的提高 代码如下

file

file

LeetCode 387

题目 —— 字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
示例:

s = “leetcode”
返回 0

s = “loveleetcode”
返回 2

提示:你可以假定该字符串只包含小写字母。

思路

这到题 瞬间 双重遍历每一字符遍历对比一遍 没有出现的其实就是想要的解 时间复杂度O( n^2 ) 然后瞬间推翻 提示不是没用的 猜测一定O(n)内可以解决

  • O(n)内解决 肯定一两次循环就够
  • 提示:你可以假定该字符串只包含小写字母。 那么根据上面的经验,char可以通过ascii转成int 最多26个

所以可以得出

  • int[] 记录没有展示string中字符出现的次数 一次遍历
  • 再遍历 找到第一个次数为1的
    时间复杂度O(n);
解题

file

时间复杂度 和空间 复杂度 都在90%以上足够

复盘看下答案
  1. 官方解法一和我们思路基本一致
  2. 官方解法二 比我们方式要好 为什么 ?(具解法有兴趣的可以官网去看)
    • 利用String 方法str.indexOf(ch) == str.lastIndexOf(ch) 判断是否有过重复 减少第一次循环次数
    • 利用一共小写字母是26个 把我们第二个循环退化成了26次

LeetCode 389

题目 —— 找不同

给定两个字符串 s 和 t,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

思路
  • 延续上面套路 还是list记录 出现次数容易可以得出如下代码
解题

file

复盘看下答案

发现一个更好的解决方案 ,官方合理的利用了 随机位置添加一个字母 这个条件

利用减法 将两个字符串的ascii 做差 那么差值就是 差出来的那一个字符

代码如下
file

对比
file

虽然两次的运行时间差别不大 但是在内存上 差别还是挺明显的 毕竟数组直接退化成一个值了

LeetCode 2

题目 —— 两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

思路

抽离核心点

  1. 逆序链表
  2. 非负
  3. 一个节点一个数

综上所诉 其实最核心的就是逆序列表->链表头部是个位
题目很符合人类认知 两个链表同时后移相加 再一个变量记录进位就好了

解题

file

复盘看下答案

看了下答案 发现思路基本一致 不过在结题过程中 发现 这个题还有一个隐形的考察点 其实就是边界条件 结题的方式其实很简单 ,但是想要一次写出来也是不容易的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值