【2021.3】 LeetCode每日一题复盘

March 1st - March 7th

在这里插入图片描述

Average of Levels in Binary Tree

题目大意:
有一棵二叉树,返回二叉树每一层节点值的平均值的列表。

思路:
很自然的想到了二叉树的层序遍历。为了得到每一层节点值的平均值,要先得到节点个数和该层节点值的总和。当前层的节点个数就是一开始队列中节点的个数,内部再加一层循环,表示对当前层的遍历。

提示知识点:

  1. 数据结构队列定义 Queue LinkedList
  2. Queue 的基本操作: size() ,offer(),poll()
  3. 入队左子节点和右子节点时判空

代码链接:
637.average-of-levels-in-binary-tree.java

Short Encoding of Words

题目大意:
有一个字符串数组,数组每个字符串是个单词,将这些单词重编码为一个新的字符串。编码后,每个单词都是新字符串的子串且都以#结尾,求满足要求的新字符串的最短长度。

思路:
将单词用Set存储,遍历每个单词,从Set中移除单词的所有子串。
然后遍历Set,求出最短长度。

提示知识点:

  1. Set array转Set, remove()
  2. String的substring()。

代码链接:
820.short-encoding-of-words.java

Design HashMap

题目大意:
这是一道设计题,要求实现HashMap的功能

思路:
题目有限制,key和value均为[0,10^6]的整数,因此一开始就把数组大小设置为1000001,而不必去考虑HashMap的扩容等工程问题。
关于HashMap的底层原理倒是可以再详细去研究下。

提示知识点:
集合类封装

代码链接:
706.design-hash-map.java

March 8th - March 14th

在这里插入图片描述

Add One Row to Tree

题目大意:
有一棵二叉树,给出深度d和节点值v,在树中插入新的一层作为第d层,该层节点值都为v,之前的左节点为新节点的左节点,之前右节点为新节点的右节点。根节点为第1层,若在第一层加入一层,则原来的根节点变为左节点。

思路:
逐层下降,当d为2时,进行插入层操作,当d大于2时,递归遍历左右子树节点,d减1。

提示知识点:

  1. 树的递归
  2. 根节点为空,函数直接返回。

代码链接:
623.add-one-row-to-tree.java

Integer to Roman

题目大意:
将整数转为罗马数字

思路:

  1. 整数范围限制在[1,3999],因此用数组表示出千百十个位上相应的表示,然后依次取出整数各个数位的罗马数字表示,按千百十个从左到右拼接起来。
  2. 注意每一位上4和9的表示略有不同。不使用数组,可以用当前数字去循环减一个基数,每减一次就拼接一个罗马字符串,基数按照10,9,4,1递减。

提示知识点:
数学

代码链接:
12.integer-to-roman.java

Coin Change

题目大意:
给出硬币面值数组和指定金额,用尽可能少的硬币数量兑换指定金额。假设每种面值的硬币有无数多。

思路:
将硬币面值按从小到大排序。

  1. amounts[i]为外层循环, coins[j]为内层循环
    i>=coins[j]时的动态规划方程:
    amounts[i] = amounts[i]==-1 ? amounts[i-coins[j]]+1 : Math.min(amounts[i], amounts[i-coins[j]]+1);
  2. coins[i]为外层循环, arr[j]为内层循环
    arr[j] = Math.min(arr[j],arr[j-coins[i]] + 1);

提示知识点:
动态规划

代码链接:
322.coin-change.java

Check If a String Contains All Binary Codes of Size K

题目大意:
检查一个字符串是否包含所有长度为K的二进制编码。比如K=2, 00110 包含所有长度为2的二进制编码(00,01,10,11)。

思路:
换一种思路,不去管所有的二进制编码是什么样的,我们只知道长度为K的二进制编码有(2^K)种 。遍历字符串长度为K的子串,并添加到Set,添加成功记录个数,如果个数达到最大种数则包含所有。如果遍历完整个字符串仍然没达到(2^K),则不包含。

提示知识点:

  1. 位运算符 << 求(2^K)
  2. Set去重
  3. String的substring()

代码链接:
1461.check-if-a-string-contains-all-binary-codes-of-size-k.java

Swapping Nodes in a Linked List

题目大意:
交换链表正序第K个节点和逆序第K个节点的值

思路:
先遍历到正序第K个节点,然后记录头节点指针p1,第K个节点指针p2,继续同时移动p2和p1,当p2指向最后一个节点时,p1指向的就是逆序第K个节点。

提示知识点:

  1. 双指针。
  2. 链表遍历,异常情况考虑判断空指针。

代码链接:
1721.swapping-nodes-in-a-linked-list.java

March 15th - March 21st

在这里插入图片描述

Encode and Decode TinyURL

题目大意:
编码和解码URL,即可以对URL按照一定格式编码,也可以根据编码后的字符串得到原始URL。

思路:
使用HashMap存储编码和原始URL的映射关系。编码可由URL生成其唯一标识,一种解法是随机生成UUID,重复概率小。

提示知识点:

  1. HashMap
  2. UUID.randomUUID()
  3. String的substring() indexOf()

代码链接:
535.encode-and-decode-tiny-url.java

Best Time to Buy and Sell Stock with Transaction Fee

题目大意:
买卖股票使得收益最大,不能同时进行多个交易,先出售股票才能再购买。

思路:
为了从第i天过渡到第i+1天,要么出售股票,cash = max(cash, hold + prices[i] - fee),要么购买股票hold = max(hold, cash - prices[i])。最后,要返回cash。

提示知识点:
动态规划

代码链接:
714.best-time-to-buy-and-sell-stock-with-transaction-fee.java

Generate Random Point in a Circle

题目大意:
给出圆心坐标和圆半径,随机返回一个圆内点的坐标。

思路:
圆心(x0,y0),半径r,则圆内点坐标范围(x0±r, y0±r)。在圆内还需满足条件:到圆心距离小于等于r。

提示知识点:
数学。Math.random()生成范围为(0,1)的double数,那么要生成范围
(-r, r),则为(Math.random()*2 - 1) * r。

代码链接:
478.generate-random-point-in-a-circle.java

Wiggle Subsequence

题目大意:

思路:

提示知识点:

代码链接:
376.wiggle-subsequence.java

Keys and Rooms

题目大意:
每个房间有若干进入其他房间的钥匙,问能否从房间0开始,进入每个房间?

思路:
需要一个房间是否被访问的标记数组。从房间0开始深度遍历,循环获得房间1到房间i的钥匙,若房间i未被访问,则将其作为新的起点,继续深度遍历。
结束后遍历标记数组,若都为true,则表示能从房间0进入所有房间,反之不能。

提示知识点:
深度优先遍历。

代码链接:
841.keys-and-rooms.java

Design Underground System

题目大意:
设计一个地铁系统。这个系统支持的功能:追踪乘客(ID)进站/出站的时刻。计算两站之间所有乘客花费时间的平均值。

思路:
需要两个Map,一个Map记录乘客的进站时间,另一个Map记录出站到进站的信息(所有记录数和总时间)映射,也即是第二个Map是Map的Map。
如果输入为checkIn,则更新第一个Map。
如果输入为check Out,则读取第一个Map乘客的入站信息,更新第二个Map,将两站之间信息的记录数加一,时间加上此次乘坐耗费的时间。
如果输入为读取平均值,直接读取第二个Map,计算平均值。

提示知识点:

  1. HashMap put(),get()
  2. 类的封装

代码链接:
1396.design-underground-system.java

Reordered Power of 2

题目大意:
重排序一个整数的数位,得到的数能否是2的幂

思路:
我们将这个数和2的幂的分别转为字符数组,排序然后转为新的两个字符串。若两字符串相同则能,不相同则不能。
整数范围为(0,10^9),因此最多比较到2的30幂次即可。

提示知识点:

  1. 位运算
  2. 字符串和字符数组互转

代码链接:
869.reordered-power-of-2.java

March 22nd - March 28th

在这里插入图片描述

Vowel Spellchecker

题目大意:
元音字母拼写检查。在单词列表中查询一个单词,如果输入单词恰好和列表中相同,则直接返回;如果大小写不一致或/和元音字母被其他元音字母替换,也返回第一个匹配的原单词,规则是先匹配大小写不一致再匹配元音字母不一致的情况。

思路:
需要一个Set存储单词列表中的单词。两个Map,一个Map的Key为对原单词全小写转换后的字符串,另一个Map的Key是对原单词中元音字母进行去元音字母处理的新串。只当Key不存在时,put原串到Map中。
查询时则对查询串进行相应处理,先查询原始串,再小写化处理后查询,最后去元音化处理查询,一旦匹配查询终止,三轮查询结束无匹配返回空串。

提示知识点:
HashMap 的putIfAbsent()和containsKey()

代码链接:
966.vowel-spellchecker.java

3Sum With Multiplicity

题目大意:
数组中 i, j, k 满足 i < j < k且 arr[i] + arr[j] + arr[k] == target的组合个数。

思路:
3sum问题的变式,遵循3sum问题的双指针法,先对数组排序,小于target移动左指针,大于target移动右指针。

计算组合个数时,与arr[i]值相同但下标i不同的应视为不同情况,不能简单跳过。对于同一个i, j和k可分别统计相同元素的个数,然后计算组合数nm,特别地arr[j]==arr[k]时,计算组合数为n(n-1)/2。

提示知识点:

  1. 双指针。
  2. 考虑特殊测试用例。

代码链接:
923.3-sum-with-multiplicity.java

Advantage Shuffle

题目大意:
优势翻转,翻转数组A,使得最多的下标i满足A[i] > B[i]。

思路:
田忌赛马。
为了使得满足要求的下标最多,我们总是用数组A中最小的元素去与数组B中的最小的元素比较。
先复制两个数组,再对A和B进行排序。需要一个Map和一个链表,Map中存储B中数组值B与可与之对应的A中元素值的链表assigned(一个值可能在B中出现多次,重组时依次出队取出),另一个链表remaining存储无法用来获取优势的值,重组时,若Map中不存在键B[i],则出队remaining中一个元素放入重组的位置,逐一比较排序后两数组的元素,最后重组结果数组。

提示知识点:

  1. 贪心
  2. 队列基本操作

代码链接:
870.advantage-shuffle.java

Pacific Atlantic Water Flow

题目大意:
求大陆上水流既能流向太平洋又能流向大西洋的单元坐标。水流可沿四个方向,从高位置向低位置流动。太平洋在陆地左上边界,大西洋在右下边界。

思路:
逆向深度遍历。陆地左边界和上边界的点一定可以流入太平洋,同理右边界和下边界的点也一定可以流入大西洋。从这些点出发进行深度遍历,可以抵达的点也一定可以流入对应海洋。注意这个抵达与水流方向恰好相反,即如果新的位置比旧的位置高或相等,那么遍历能够抵达。维护两个二维数组,分别表示能否流向太平洋和大西洋。遍历完成后,同时遍历这两个数组得出题目所求的点坐标集合。

提示知识点:
深度优先遍历

代码链接:
417.pacific-atlantic-water-flow.java

Word Subsets

题目大意:

思路:

提示知识点:

代码链接:
916.word-subsets.java

Palindromic Substrings

题目大意:

思路:

提示知识点:

代码链接:
647.palindromic-substrings.java

Reconstruct Original Digits from English

题目大意:

思路:

提示知识点:

代码链接:
423.reconstruct-original-digits-from-english.java

March 29th - March 31st

在这里插入图片描述

Flip Binary Tree To Match Preorder Traversal

题目大意:

思路:

提示知识点:

代码链接:
971.flip-binary-tree-to-match-preorder-traversal.java

Russian Doll Envelopes

题目大意:

思路:

提示知识点:

代码链接:
354.russian-doll-envelopes.java

Stamping The Sequence

题目大意:

思路:

提示知识点:

代码链接:
936.stamping-the-sequence.java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wsws100

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

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

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

打赏作者

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

抵扣说明:

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

余额充值