LeetCode——模拟

48.旋转图象

方法:(以下两步翻转可以互换)

  1. 主对角线翻转
  2. 竖中轴翻转

54.螺旋数组

最开始的想法是循环,每次循环或向右,或向下,或向左,或向上

之后发现,一轮顺时针遍历是由向右,向下,向左,向上四个操作组成,不应该分割。如此循环若干次(对矩阵进行若干次顺时针遍历)值,直到遍历完整个矩阵。

59.螺旋矩阵II

方法:设定边界+模拟 。用四个变量表示当前矩阵的边界,然后将元素一个一个地填入。
需要注意的是:在到达每一条边的边界时需要及时更新边界。

65.有效数字

方法

  1. 正则表达式(我不会,需要学习)
  2. 有限状态机(官方题解)
  3. 讨论所有可能的情况,这是我第一次用的方法。

这里补充一下第三种解法。有效数字有这么几种可能

  1. 整数
  2. 小数
  3. 整数e/E整数
  4. 小数e/E整数

66.加一

方法:大数加法 + copy_backward()

73.矩阵置零

方法:使用行数组和列数组分别指示行和列是否有元素为0。 空间复杂度O(m + n)。

88.合并两个有序数组

223.矩形面积

计算重叠面积,然后用总面积减去重叠面积。

要画图,考虑各种可能的情况

矩形的放置有两种情况:

  1. 矩形交叠。如果两个矩形交叠,
  2. 矩形不交叠。

两个矩形的水平边投影到x轴上的线段分别为[ax1,ax2][bx1,bx2]。竖直边投影到y轴的线段有[ay1,ay2]by1,by2]

如果两个矩形交叠,重叠部分的水平投影是[max(ax1,bx2),min(ax2,bx2)],竖直部分的水平投影是[max(ay1,by2),min(ay2,by2)].

根据重叠部分的线段可计算重叠部分的面积。只有重叠线段都大于0,重叠面积才会大于0,否则就为0

228.汇总区间

题目给定的数字有正有负,为了保证数字转字符串的正确性,要先把数字转为正数,最后再根据数字是否大于0决定是否加-。这时候要特别小心边界条件:极小值的相反数超过了int的表示范围,因此要做相应的检查判断。

下面两道题目都用到了 摩尔投票算法

摩尔投票算法可以这么理解:
假设现在有 n n n个投票人, k k k个候选人。初始时 k k k个候选人的位置都是空。在投票的过程中,每一个投票人走上投票台,按照如下规则进行投票:

  1. 如果他在候选人中看到和自己同名的人,那么就把票投给他;
  2. 如果看到有候选人的票数是零,就把候选人请下台,然后自己走到候选人的位置,并给自己投一票
  3. 如果既没看到和自己名字相同的人,也没看到候选人的票数是零,就拿走所有候选人的一张选票。

重复上述过程,直到所有人都上过一次投票台。

169.多数元素
229.多数元素II

289.生命游戏

思路和算法:

  1. 复制原数组,用复制的数组状态改变原数组的状态

  2. 引入多余的状态在原地修改。具体而言;

    1. 细胞状态原来是活的,但现在死亡,用状态-1标识
    2. 细胞状态原来是死的,但现在活了,用状态2标识

    最后再遍历一遍数组,把状态-12改为01


388.文件的最长绝对路径

算法和思路

  • 题目要求求解文件的最长绝对路径,有两个需要注意的地方:

    1. 是文件,而不是文件夹
    2. 最长的绝对路径
  • 观察题目,不难发现每当出现字符\n时,就进入了新一级目录,\n后面\t的个数表示目录的级数。

  • 假设文件处于第 n n n级,要求得文件的最长的绝对路径,必须保存该文件前 n − 1 n - 1 n1目录(包括第0级根目录)。

  • 注意到遍历完第一个1级目录的下面所有子目录后,才能遍历第二个1级目录

通过以上分析,可以提出如下算法:

  1. vector<string>保存当前所遍历到的文件/文件夹的前面所有级的文件目录
  2. 遇到\n,根据\t的个数判断当前文件/文件夹所在的目录级数
  3. 遇到其他字母,一直读取,直到遇到\n结束。若当前字符串中存在.,说明它是一个文件,计算该文件的绝对路径,并更新结果;否则它是一个文件夹,将文件夹加入到vector<string>的第 n n n个位置。
  4. 重复2-3,直到结束遍历。
小贴士

\n\t都是一个字符,而非两个。


415. 字符串相加

方法:大数加法

具体而言,把字符串表示的数字按照从低位到高位的顺序依次存入vector中,然后用两个vector模拟加法运算,并把结果存放到结果vector中,最后把结果vector转为字符串。


420.强密码检测器

一道困难又无聊的模拟题。


423.从英文中重建数字

这是一道简单的模拟题。

首先写出0-9的英文表示:zero one two three four five six seven eight nine

观察以上英文单词,不难发现如下规律:

  1. z 唯一确定 zero
  2. w 唯一确定 two
  3. u 唯一确定 four
  4. x 唯一确定 six
  5. g 唯一确定 eight
  6. zero, one,two, four共有 o,确定zero,two,four,即可确定one
  7. zero, four, three 共有r, 确定了fourzero 即可确定three
  8. fourfive 共有 f,确定了four即可确定fivev
  9. sixseven 共有 s, 确定了six即可确定seven
  10. five,six,eight,nine共有i,确定了five,six,eight即可确定nine

按照上述规律,提出了如下的算法:

  1. 统计字符串中字符的频次
  2. 按照上述规律根据字符频次确定数字个数

440.字典序的第K小数字

题目类型:数位统计。数位统计问题一般都是按位统计。

1. 思路和算法

在本题中,按位查找数字前缀。因此,需要定义一个函数int f(int prefix, int n),该函数的作用返回[1,n]中数字前缀是prefix的数字个数cnt

  1. cnt < k,要找的数字的前缀大于prefix,因此递增prefix(因为 k ≤ n k \leq n kn,所以不需要考虑prefix递增的溢出问题),并更新kk - cnt
  2. cnt >= k,说明目标数字的前缀是prefix,需要进一步确定前缀的下一个数字,因此从 p r e f i x × 10 prefix \times 10 prefix×10开始查找,同时-- k。(为什么prefix也不仅是一个前缀,还是一个数字。以prefix为前缀的数字中就包含prefix本身。因为下一步查找的是 p r e f i x × 10 prefix \times 10 prefix×10,而以 p r e f i x × 10 prefix \times 10 prefix×10为前缀的数字不包含prefix,因此搜索范围k也要相应地缩小)。
  3. 重复上述操作,直到k = 1

2. 函数int f(int prefix, int n)

设前缀prefixx位,ny位,以prefix为前缀的数字num可以是 x x x位, x + 1 x + 1 x+1位, ⋯ \cdots y y y位。

num的位数是z

  1. x ≤ z < y x \leq z < y xz<y,共有 1 0 z − x 10^{z - x} 10zx个数字的前缀是prefix
  2. z = y z = y z=y
    1. 若数字n的前x位大于prefix,共有 1 0 y − z 10 ^ {y - z} 10yz个数字前缀是prefix
    2. 若数字n的前x位大于prefix,共有 n − p r e f i x × 1 0 y − z + 1 n - prefix \times 10 ^ {y - z} + 1 nprefix×10yz+1个数字前缀是prefix
    3. 若数字n的前x位小于于prefix,共有 0 0 0个数字前缀是prefix

453.最小操作次数使数组元素相等
个人认为这道题目还是很锻炼问题的抽象能力的。

任选$ n - 1 $个元素加 1 1 1,等价于任选 1 1 1个元素减 1 1 1。因为因为我们关心的不是最终的相等元素是什么,而是元素之间的相对值。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值