Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[pull] main from itcharge:main #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
pull merged 1 commit into AlgorithmAndLeetCode:main from itcharge:main
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,34 @@

## 题目大意

给定一个升序数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。要求使用时间复杂度为 $O(log n)$ 的算法解决问题。
**描述**:给你一个按照非递减顺序排列的整数数组 `nums`,和一个目标值 `target`。

**要求**:找出给定目标值在数组中的开始位置和结束位置。

**说明**:

- 要求使用时间复杂度为 $O(\log n)$ 的算法解决问题。

**示例**:

```Python
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]


输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
```

## 解题思路

要求使用时间复杂度为 $O(logn)$ 的算法解决问题,那么就需要使用「二分查找算法」了。这道题明显就是对「二分查找」的考察。
### 思路 1:二分查找

进行两次二分查找,第一次尽量向左搜索。第二次尽量向右搜索
要求使用时间复杂度为 $O(\log n)$ 的算法解决问题,那么就需要使用「二分查找算法」了

## 代码
- 进行两次二分查找,第一次尽量向左搜索。第二次尽量向右搜索。

### 思路 1:代码

```Python
class Solution:
Expand Down Expand Up @@ -52,3 +71,7 @@ class Solution:
return ans
```

### 思路 1:复杂度分析

- **时间复杂度**:$O(\log_2 n)$。
- **空间复杂度**:$O(1)$。
40 changes: 36 additions & 4 deletions Solutions/0056. 合并区间.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,42 @@

## 题目大意

数组 intervals 表示若干个区间的集合。请合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需要恰好覆盖原数组中的所有区间。
**描述**:给定数组 `intervals` 表示若干个区间的集合,其中单个区间为 `intervals[i] = [starti, endi]` 。

**要求**:合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

**说明**:

- 1ドル \le intervals.length \le 10^4$。
- $intervals[i].length == 2$。
- 0ドル \le starti \le endi \le 10^4$。

**示例**:

```Python
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].


输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
```

## 解题思路

设定一个数组 ans 用于表示最终不重叠的区间数组,然后对原始区间先按照区间左端点大小从小到大进行排序。
### 思路 1:排序

遍历所有区间。先将第一个区间加入 ans 数组中。然后依次考虑后边的区间,如果第 i 个区间左端点在前一个区间右端点右侧,则这两个区间不会重合,直接将该区间加入 ans 数组中。否则的话,这两个区间重合,判断一下两个区间的右区间值,更新前一个区间的右区间值为较大值,然后继续考虑下一个区间,以此类推。
1. 设定一个数组 `ans` 用于表示最终不重叠的区间数组,然后对原始区间先按照区间左端点大小从小到大进行排序。
2. 遍历所有区间。
3. 先将第一个区间加入 `ans` 数组中。
4. 然后依次考虑后边的区间:
1. 如果第 `i` 个区间左端点在前一个区间右端点右侧,则这两个区间不会重合,直接将该区间加入 `ans` 数组中。
2. 否则的话,这两个区间重合,判断一下两个区间的右区间值,更新前一个区间的右区间值为较大值,然后继续考虑下一个区间,以此类推。
5. 最后返回数组 `ans`。

##代码
### 思路 1:代码

```Python
class Solution:
Expand All @@ -29,3 +56,8 @@ class Solution:
return ans
```

### 思路 1:复杂度分析

- **时间复杂度**:$O(n \times \log_2 n)$。其中 $n$ 为区间数量。
- **空间复杂度**:$O(n)$。

40 changes: 36 additions & 4 deletions Solutions/0088. 合并两个有序数组.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,43 @@

## 题目大意

给定两个有序数组 `nums1`、`nums2`。将 `nums2` 合并到 `nums1` 中,使 `nums1` 成为一个有序数组
**描述**:给定两个有序数组 `nums1`、`nums2`。

其中给定数组 nums1 空间大小为 m + n 个,其中前 m 个为 nums1 的元素。`nums2` 空间大小为 n。这样可以用 `nums1` 的空间来存储最终的有序数组。
**要求**:将 `nums2` 合并到 `nums1` 中,使 `nums1` 成为一个有序数组。

**说明**:

- 给定数组 `nums1` 空间大小为` m + n` 个,其中前 `m` 个为 `nums1` 的元素。`nums2` 空间大小为 `n`。这样可以用 `nums1` 的空间来存储最终的有序数组。
- $nums1.length == m + n$。
- $nums2.length == n$。
- 0ドル \le m, n \le 200$。
- 1ドル \le m + n \le 200$。
- $-10^9 \le nums1[i], nums2[j] \le 10^9$。

**示例**:

```Python
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:需要合并 [1,2,3] 和 [2,5,6] 。
合并结果是 [1,2,2,3,5,6] ,其中斜体加粗标注的为 nums1 中的元素。


输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]
解释:需要合并 [1] 和 [] 。
合并结果是 [1] 。
```

## 解题思路

将两个指针 index1、index2 分别指向 nums1、nums2 元素的尾部,再用一个指针 index 指向数组 nums1 的尾部。从后向前判断当前指针下 nums1[index1] 和 nums[index2] 的值大小,将较大值存入 num1[index] 中,然后继续向前遍历。最后再将 nums 中剩余元素赋值到 num1 前面对应位置上。
### 思路 1:快慢指针

## 代码
1. 将两个指针 `index1`、`index2` 分别指向 `nums1`、`nums2` 数组的尾部,再用一个指针 `index` 指向数组 `nums1` 的尾部。
2. 从后向前判断当前指针下 `nums1[index1]` 和 `nums[index2]` 的值大小,将较大值存入 `num1[index]` 中,然后继续向前遍历。
3. 最后再将 `nums2` 中剩余元素赋值到 `num1` 前面对应位置上。

### 思路 1:代码

```Python
class Solution:
Expand All @@ -33,3 +61,7 @@ class Solution:
nums1[:index2+1] = nums2[:index2+1]
```

### 思路 1:复杂度分析

- **时间复杂度**:$O(m + n)$。
- **空间复杂度**:$O(m + n)$。
41 changes: 33 additions & 8 deletions Solutions/0136. 只出现一次的数字.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,42 @@

## 题目大意

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。要求不能使用额外的存储空间。
**描述**:给定一个非空整数数组 `nums`,`nums` 中除了某个元素只出现一次以外,其余每个元素均出现两次。

**要求**:找出那个只出现了一次的元素。

**说明**:

- 要求不能使用额外的存储空间。

**示例**:

```Python
输入: [2,2,1]
输出: 1


输入: [4,1,2,1,2]
输出: 4
```

## 解题思路

如果没有时间复杂度和空间复杂度的限制,可以使用字典来存储每个元素出现的次数,或者用集合来存储数字,如果集合中没有该数字,则将该数字加入集合,如果集合中有了该数字,则从集合中删除该数字,最终成对的数字都被删除了,只剩下单次出现的元素。
### 思路 1:位运算

如果考虑不使用额外的存储空间,就需要用到位运算中的异或运算。对 n 个数不断进行异或操作,最终可得到单次出现的元素
如果没有时间复杂度和空间复杂度的限制,可以使用哈希表 / 集合来存储每个元素出现的次数,如果哈希表中没有该数字,则将该数字加入集合,如果集合中有了该数字,则从集合中删除该数字,最终成对的数字都被删除了,只剩下单次出现的元素

> 异或运算 ⊕ 的三个性质:
但是题目要求不使用额外的存储空间,就需要用到位运算中的异或运算。

> 异或运算 $\oplus$ 的三个性质:
>
> 1. 任何数和 0 做异或运算,结果仍然是原来的数,即 a ⊕ 0 = a。
> 2. 数和其自身做异或运算,结果是 0,即 a ⊕ a = 0。
> 3. 异或运算满足交换率和结合律:a ⊕ b ⊕ a = b ⊕ a ⊕ a = b ⊕ (a ⊕ a) = b ⊕ 0 = b。
> 1. 任何数和 0ドル$ 做异或运算,结果仍然是原来的数,即 $a \oplus 0 = a$。
> 2. 数和其自身做异或运算,结果是 0ドル,ドル即 $a \oplus a = 0$。
> 3. 异或运算满足交换率和结合律:$a \oplus b \oplus a = b \oplus a \oplus a = b \oplus (a \oplus a) = b \oplus 0 = b$。

根据异或运算的性质,对 $n$ 个数不断进行异或操作,最终可得到单次出现的元素。

##代码
### 思路 1:代码

```Python
class Solution:
Expand All @@ -32,3 +53,7 @@ class Solution:
return ans
```

### 思路 1:复杂度分析

- **时间复杂度**:$O(n)$。
- **空间复杂度**:$O(1)$。
35 changes: 28 additions & 7 deletions Solutions/0169. 多数元素.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,36 @@

## 题目大意

给定一个数组,找到其中相同元素个数最多的元素
**描述**:给定一个大小为 $n$ 的数组 `nums`

## 解题思路
**要求**:返回其中相同元素个数最多的元素。

**说明**:

- $n == nums.length$。
- 1ドル \le n \le 5 * 10^4$。
- $-10^9 \le nums[i] \le 10^9$。

**示例**:

```Python
输入:nums = [3,2,3]
输出:3

可以利用哈希表。

遍历一遍数组 nums,用哈希表统计每个元素 num 出现的次数,再遍历一遍哈希表,找出元素个数最多的元素即可。
输入:nums = [2,2,1,1,1,2,2]
输出:2
```

时间复杂度为:O(N)
## 解题思路

空间复杂度为:O(N)
### 思路 1:哈希表

## 代码
1. 遍历数组 `nums`。
2. 对于当前元素 `num`,用哈希表统计每个元素 `num` 出现的次数。
3. 再遍历一遍哈希表,找出元素个数最多的元素即可。

### 思路 1:代码

```Python
class Solution:
Expand All @@ -37,3 +54,7 @@ class Solution:
return max_index
```

### 思路 1:复杂度分析

- **时间复杂度**:$O(n)$。
- **空间复杂度**:$O(n)$。
30 changes: 26 additions & 4 deletions Solutions/0179. 最大数.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,35 @@

## 题目大意

给定一个非负整数数组 `nums`。
**描述**:给定一个非负整数数组 `nums`。

要求:将数组中的数字拼接起来排成一个数,打印能拼接出的所有数字中的最大的一个。
**要求**:重新排列数组中每个数的顺序,使之将数组中所有数字按顺序拼接起来所组成的整数最大。

**说明**:

- 1ドル \le nums.length \le 100$。
- 0ドル \le nums[i] \le 10^9$。

**示例**:

```Python
输入:nums = [10,2]
输出:"210"


输入:nums = [3,30,34,5,9]
输出:"9534330"
```

## 解题思路

### 思路 1:排序

本质上是给数组进行排序。假设 `x`、`y` 是数组 `nums` 中的两个元素。如果拼接字符串 `x + y < y + x`,则 `y > x `。`y` 应该排在 `x` 前面。反之,则 `y < x`。

按照上述规则,对原数组进行排序即可。这里使用了 `functools.cmp_to_key` 自定义排序函数。
按照上述规则,对原数组进行排序即可。这里我们使用了 `functools.cmp_to_key` 自定义排序函数。

##代码
### 思路 1:代码

```Python
import functools
Expand All @@ -34,3 +52,7 @@ class Solution:
return str(int(''.join(nums_s)))
```

### 思路 1:复杂度分析

- **时间复杂度**:$O(n^2)$。其中 $n$ 是给定数组 `nums` 的大小。
- **空间复杂度**:$O(n)$。

AltStyle によって変換されたページ (->オリジナル) /