Skip to content

Commit

Permalink
feat: $686
Browse files Browse the repository at this point in the history
  • Loading branch information
lucifer committed Oct 28, 2020
1 parent 2d99ffb commit 2a7de26
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 9 deletions.
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
* [0560. 和为K的子数组](problems/560.subarray-sum-equals-k.md)
* [0609. 在系统中查找重复文件](problems/609.find-duplicate-file-in-system.md)
* [0611. 有效三角形的个数](problems/611.valid-triangle-number.md)
* [0686. 重复叠加字符串匹配](problems/686.repeated-string-match.md)
* [0718. 最长重复子数组](problems/718.maximum-length-of-repeated-subarray.md)
* [0754. 到达终点数字](problems/754.reach-a-number.md)
* [0785. 判断二分图](problems/785.is-graph-bipartite.md)
Expand Down
15 changes: 8 additions & 7 deletions collections/medium.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
- [0011. 盛最多水的容器](../problems/11.container-with-most-water.md)
- [0015. 三数之和](../problems/15.3sum.md)
- [0017. 电话号码的字母组合](../problems/17.Letter-Combinations-of-a-Phone-Number.md)
- [0019. 删除链表的倒数第N个节点](../problems/19.removeNthNodeFromEndofList.md)
- [0019. 删除链表的倒数第 N 个节点](../problems/19.removeNthNodeFromEndofList.md)
- [0022. 括号生成](../problems/22.generate-parentheses.md)
- [0024. 两两交换链表中的节点](../problems/24.swapNodesInPairs.md)
- [0029. 两数相除](../problems/29.divide-two-integers.md)
Expand All @@ -29,7 +29,7 @@
- [0050. Pow(x, n)](../problems/50.pow-x-n.md)
- [0055. 跳跃游戏](../problems/55.jump-game.md)
- [0056. 合并区间](../problems/56.merge-intervals.md)
- [0060. 第k个排列](../problems/60.permutation-sequence.md)
- [0060. 第 k 个排列](../problems/60.permutation-sequence.md)
- [0062. 不同路径](../problems/62.unique-paths.md)
- [0073. 矩阵置零](../problems/73.set-matrix-zeroes.md)
- [0075. 颜色分类](../problems/75.sort-colors.md)
Expand Down Expand Up @@ -59,11 +59,11 @@
- [0201. 数字范围按位与](../problems/201.bitwise-and-of-numbers-range.md)
- [0208. 实现 Trie (前缀树)](../problems/208.implement-trie-prefix-tree.md)
- [0209. 长度最小的子数组](../problems/209.minimum-size-subarray-sum.md)
- [0211. 添加与搜索单词 * 数据结构设计](../problems/211.add-and-search-word-data-structure-design.md)
- [0215. 数组中的第K个最大元素](../problems/215.kth-largest-element-in-an-array.md)
- [0211. 添加与搜索单词 \* 数据结构设计](../problems/211.add-and-search-word-data-structure-design.md)
- [0215. 数组中的第 K 个最大元素](../problems/215.kth-largest-element-in-an-array.md)
- [0221. 最大正方形](../problems/221.maximal-square.md)
- [0229. 求众数 II](../problems/229.majority-element-ii.md)
- [0230. 二叉搜索树中第K小的元素](../problems/230.kth-smallest-element-in-a-bst.md)
- [0230. 二叉搜索树中第 K 小的元素](../problems/230.kth-smallest-element-in-a-bst.md)
- [0236. 二叉树的最近公共祖先](../problems/236.lowest-common-ancestor-of-a-binary-tree.md)
- [0238. 除自身以外数组的乘积](../problems/238.product-of-array-except-self.md)
- [0240. 搜索二维矩阵 II](../problems/240.search-a-2-d-matrix-ii.md)
Expand All @@ -75,7 +75,7 @@
- [0337. 打家劫舍 III](../problems/337.house-robber-iii.md)
- [0343. 整数拆分](../problems/343.integer-break.md)
- [0365. 水壶问题](../problems/365.water-and-jug-problem.md)
- [0378. 有序矩阵中第K小的元素](../problems/378.kth-smallest-element-in-a-sorted-matrix.md)
- [0378. 有序矩阵中第 K 小的元素](../problems/378.kth-smallest-element-in-a-sorted-matrix.md)
- [0380. 常数时间插入、删除和获取随机元素](../problems/380.insert-delete-getrandom-o1.md)
- [0416. 分割等和子集](../problems/416.partition-equal-subset-sum.md)
- [0445. 两数相加 II](../problems/445.add-two-numbers-ii.md)
Expand All @@ -84,9 +84,10 @@
- [0516. 最长回文子序列](../problems/516.longest-palindromic-subsequence.md)
- [0518. 零钱兑换 II](../problems/518.coin-change-2.md)
- [0547. 朋友圈](../problems/547.friend-circles.md)
- [0560. 和为K的子数组](../problems/560.subarray-sum-equals-k.md)
- [0560. 和为 K 的子数组](../problems/560.subarray-sum-equals-k.md)
- [0609. 在系统中查找重复文件](../problems/609.find-duplicate-file-in-system.md)
- [0611. 有效三角形的个数](../problems/611.valid-triangle-number.md)
- [0686. 重复叠加字符串匹配](../problems/686.repeated-string-match.md) 🆕
- [0718. 最长重复子数组](../problems/718.maximum-length-of-repeated-subarray.md)
- [0754. 到达终点数字](../problems/754.reach-a-number.md)
- [0785. 判断二分图](../problems/785.is-graph-bipartite.md)
Expand Down
5 changes: 3 additions & 2 deletions problems/611.valid-triangle-number.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## 题目地址(611. 有效三角形的个数)

https://leetcode-cn.com/problems/valid-triangle-number/

## 题目描述
Expand Down Expand Up @@ -29,14 +30,14 @@ https://leetcode-cn.com/problems/valid-triangle-number/
- 二分法
- 三角形边的关系

## 暴力法(超时)

## 公司

- 腾讯
- 百度
- 字节

## 暴力法(超时)

### 思路

首先要有一个数学前提: `如果三条线段中任意两条的和都大于第三边,那么这三条线段可以组成一个三角形`。即给定三个线段 a,b,c,如果满足 a + b > c and a + c > b and b + c > a,则线段 a,b,c 可以构成三角形,否则不可以。
Expand Down
138 changes: 138 additions & 0 deletions problems/686.repeated-string-match.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
## 题目地址(686. 重复叠加字符串匹配)

https://leetcode-cn.com/problems/repeated-string-match/description/

## 题目描述

```
给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1。
注意:字符串 "abc" 重复叠加 0 次是 "",重复叠加 1 次是 "abc",重复叠加 2 次是 "abcabc"。
 
示例 1:
输入:a = "abcd", b = "cdabcdab"
输出:3
解释:a 重复叠加三遍后为 "abcdabcdabcd", 此时 b 是其子串。
示例 2:
输入:a = "a", b = "aa"
输出:2
示例 3:
输入:a = "a", b = "a"
输出:1
示例 4:
输入:a = "abc", b = "wxyz"
输出:-1
 
提示:
1 <= a.length <= 104
1 <= b.length <= 104
a 和 b 由小写英文字母组成
```

## 前置知识

- set

## 公司

- 暂无

## 思路

首先,一个容易发现的点是**如果 b 中包含有 a 中没有的字符, 那么一定需要返回 - 1**。因此使用集合存储 a 和 b 的所有字符,并比较 b 是否是 a 的子集,如果不是,则直接返回 - 1。

接着我们逐个尝试:

- 两个 a 是否可以?
- 三个 a 是否可以?
- 。。。
- n 个 a 是否可以?

如果可以,则直接返回 n 即可。关于是否可以的判断, 我们可以使用任何语言自带的 indexof 算法,Python 中 可以使用 `b in a ` 判读 b 时候是 a 的子串。

代码:

```py
cnt = 1
while True:
if b in a * cnt:
return cnt
cnt += 1
return -1
```

上面的代码有 BUG,会在一些情况无限循环。比如:

```
a = "abcabcabcabc"
b = "abac"
```

因此我们必须设计出口,并返回 -1。问题的我们的上界是什么呢?

这里有个概念叫**解空间**。这是一个很重要的概念。 我举个简单的例子。 你要在一个数组 A 中找某一个数的索引,题目保证这个数字一定在数组中存在。那么这道题的解空间就是**[0, n -1]**,其中 n 为数组长度。你的解不可能在这个范围外。

回到本题,如果 a 经过 n 次可以匹配成功, 那么最终 a 的长度范围是 [len(b), 2 * len(a) + len(b)],下界是 len(b) 容易理解, 关键是上界。

还是以上面的例子来说。

```
a = "abcabcabcabc"
b = "abac"
```

abac 如果可以在其中匹配到,一定是以下几种情况:

![](https://tva1.sinaimg.cn/large/0081Kckwly1gk5a36n5qqj310106s0t6.jpg)

![](https://tva1.sinaimg.cn/large/0081Kckwly1gk5a4md3eyj30xv04y74n.jpg)

临界情况就是:

![](https://tva1.sinaimg.cn/large/0081Kckwly1gk5ah357i0j30wx07v754.jpg)

![](https://tva1.sinaimg.cn/large/0081Kckwly1gk5aft6jkhj308c03faa3.jpg)

因此最终 a 的长度的临界值就是 2 \* len(a) + len(b)。**超过这个范围再多次的叠加也没有意义。**

## 关键点解析

- 答案是有限的, 搞清楚解空间是关键

## 代码

代码支持: Python

```py
class Solution:
def repeatedStringMatch(self, a: str, b: str) -> int:
if not set(b).issubset(set(a)):
return -1
cnt = 1
while len(a * cnt) < 2 * len(a) + len(b):
if b in a * cnt:
return cnt
cnt += 1
return -1
```

**复杂度分析**

- 时间复杂度:b in a 的时间复杂度为 M + N(取决于内部算法),因此总的时间复杂度为 $O((M + N) ^ 2)$,其中 M 和 N 为 a 和 b 的长度。
- 空间复杂度:由于使用了 set,因此空间复杂度为 $O(M +N)$,其中 M 和 N 为 a 和 b 的长度。

更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。

关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。

![](https://tva1.sinaimg.cn/large/007S8ZIlly1ghlud0qh2oj30p00dwt9t.jpg)

0 comments on commit 2a7de26

Please sign in to comment.