Skip to content

Commit bbd0d2b

Browse files
committed
0034、0035、0036 solved
1 parent ae6f9cd commit bbd0d2b

File tree

15 files changed

+427
-0
lines changed

15 files changed

+427
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# LeetCode 第 34 号问题:在排序数组中查找元素的第一个和最后一个位置
2+
3+
4+
题目来源于 LeetCode 上第 34 号问题:find-first-and-last-position-of-element-in-sorted-array。题目难度为 中等。
5+
6+
### 题目描述
7+
8+
给定一个按照升序排列的整数数组 **nums**,和一个目标值 **target**。找出给定目标值在数组中的开始位置和结束位置。
9+
10+
你的算法时间复杂度必须是 **O(log n)** 级别。
11+
12+
如果数组中不存在目标值,返回 [-1, -1]
13+
14+
15+
**示例:**
16+
17+
```
18+
输入: nums = [5,7,7,8,8,10], target = 8
19+
输出: [3,4]
20+
```
21+
```
22+
输入: nums = [5,7,7,8,8,10], target = 6
23+
输出: [-1,-1]
24+
```
25+
### 题目解析
26+
27+
题目中要求了时间复杂度为O(log n),这就很清楚要使用二分查找法了。
28+
29+
首先定义两个指针变量,分别存储左右两个位置的索引。首先去找目标值的最左面的索引,通过循环为了防止元素丢失,每次保留最右面的元素,左侧的指针移动时+1。在循环结束的时候判断一下数组中是否包括目标值,不包括的话直接退出。
30+
右面的跟左侧相同,只不过正好相反。
31+
32+
33+
34+
### 动画描述
35+
36+
![](..\Animation\在排序数组中查找元素的第一个和最后一个位置.gif)
37+
38+
### 代码实现
39+
40+
```java
41+
// 34. 下一个排列
42+
// https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
43+
// 时间复杂度:O(n)
44+
// 空间复杂度:O(1)
45+
class Solution {
46+
public int[] searchRange(int[] nums, int target) {
47+
int[] res = new int[] { -1, -1 };
48+
int left = 0;
49+
int right = nums.length - 1;
50+
int l = left;
51+
int r = right;
52+
while (left < right) {
53+
int mid = (left + right) / 2;
54+
if (nums[mid] < target) {
55+
left = mid + 1;
56+
} else {
57+
right = mid;
58+
}
59+
}
60+
if (left>right||nums[left]!=target) {
61+
return new int[]{-1,-1};
62+
}
63+
while (l < r) {
64+
int mid = (l + r) / 2 + 1;
65+
if (nums[mid] > target) {
66+
r = mid - 1;
67+
} else {
68+
l = mid;
69+
}
70+
}
71+
if (left > right || left > r) {
72+
return new int[] { -1, -1 };
73+
} else {
74+
return new int[] { left, r };
75+
}
76+
}
77+
}
78+
79+
```
80+
81+
![](../../Pictures/qrcode.jpg)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
public int[] searchRange(int[] nums, int target) {
3+
int[] res = new int[] { -1, -1 };
4+
int left = 0;
5+
int right = nums.length - 1;
6+
int l = left;
7+
int r = right;
8+
while (left < right) {
9+
int mid = (left + right) / 2;
10+
if (nums[mid] < target) {
11+
left = mid + 1;
12+
} else {
13+
right = mid;
14+
}
15+
}
16+
if (left>right||nums[left]!=target) {
17+
return new int[]{-1,-1};
18+
}
19+
while (l < r) {
20+
int mid = (l + r) / 2 + 1;
21+
if (nums[mid] > target) {
22+
r = mid - 1;
23+
} else {
24+
l = mid;
25+
}
26+
}
27+
if (left > right || left > r) {
28+
return new int[] { -1, -1 };
29+
} else {
30+
return new int[] { left, r };
31+
}
32+
}
33+
}
165 Bytes
Binary file not shown.
2.86 MB
Loading
1.15 MB
Binary file not shown.
2.42 MB
Loading
1.02 MB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# LeetCode 第 35 号问题:搜索插入位置
2+
3+
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
4+
>
5+
> 同步博客:https://www.algomooc.com
6+
7+
题目来源于 LeetCode 第 35 号问题:搜索插入位置.
8+
9+
## 题目
10+
11+
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
12+
你可以假设数组中无重复元素。
13+
14+
15+
示例 1:
16+
17+
```
18+
输入: [1,3,5,6], 5
19+
输出: 2
20+
```
21+
22+
示例 2:
23+
24+
25+
```
26+
输入: [1,3,5,6], 2
27+
输出: 1
28+
```
29+
30+
示例 3:
31+
32+
33+
```
34+
输入: [1,3,5,6], 7
35+
输出: 4
36+
```
37+
38+
39+
示例 4:
40+
41+
42+
```
43+
输入: [1,3,5,6], 0
44+
输出: 0
45+
```
46+
47+
48+
49+
## 思路解析
50+
51+
### 暴力循环法
52+
53+
这个题看起来就是很简单的,就是一道考验查找算法的题目。最简单的就是暴力查找了。
54+
55+
#### 思路
56+
57+
遍历这个数组,然后如果当前值和目标值target一致或小于目标值target,那么就return 当前下标。这种解法的时间复杂度是O(N)
58+
59+
### 动画理解
60+
61+
![](../Animation/暴力查找.gif)
62+
63+
#### 代码实现
64+
65+
66+
```java
67+
//时间复杂度:O(n)
68+
//空间复杂度:O(1)
69+
class Solution {
70+
public int searchInsert(int[] nums, int target) {
71+
int i=0;
72+
for(;i<nums.length;i++){
73+
if (nums[i]>=target){
74+
break;
75+
}
76+
}
77+
return i;
78+
}
79+
}
80+
```
81+
82+
### 二分法
83+
84+
#### 思路
85+
86+
除了暴力法,我们在排序数组中查找值还可以用的一种方法是二分法,思路还是和改良的暴力循环法一样,先找到左右边界,然后计算,每次可以省出一半的时间。时间复杂度为O(logn)
87+
88+
#### 代码实现
89+
90+
```java
91+
//时间复杂度:O(lon(n))
92+
//空间复杂度:O(1)
93+
class Solution {
94+
public int searchInsert(int[] nums, int target) {
95+
if (target>nums[nums.length-1]) {
96+
return nums.length;
97+
}
98+
int left=0;
99+
int right=nums.length-1;
100+
while (left < right) {
101+
int mid = (left + right) / 2;
102+
if (nums[mid] < target) {
103+
left = mid + 1;
104+
} else {
105+
right = mid;
106+
}
107+
}
108+
return left;
109+
110+
}
111+
}
112+
```
113+
![](../../Pictures/qrcode.jpg)

Diff for: 0035-search-insert-position/Code/1.java

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Solution1 {
2+
public int searchInsert(int[] nums, int target) {
3+
int i=0;
4+
for(;i<nums.length;i++){
5+
if (nums[i]>=target){
6+
break;
7+
}
8+
}
9+
return i;
10+
}
11+
}

Diff for: 0035-search-insert-position/Code/2.java

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//时间复杂度:O(lon(n))
2+
//空间复杂度:O(1)
3+
class Solution2 {
4+
public int searchInsert(int[] nums, int target) {
5+
if (target>nums[nums.length-1]) {
6+
return nums.length;
7+
}
8+
int left=0;
9+
int right=nums.length-1;
10+
while (left < right) {
11+
int mid = (left + right) / 2;
12+
if (nums[mid] < target) {
13+
left = mid + 1;
14+
} else {
15+
right = mid;
16+
}
17+
}
18+
return left;
19+
20+
}
21+
}

Diff for: 0036-valid-sudoku/Animation/HashMap.gif

5.66 MB
Loading

Diff for: 0036-valid-sudoku/Animation/HashMap.mp4

2.66 MB
Binary file not shown.

0 commit comments

Comments
 (0)