mirror of
https://gitee.com/TheAlgorithms/LeetCodeAnimation.git
synced 2024-12-06 15:19:44 +08:00
0034、0035、0036 solved
This commit is contained in:
parent
ae6f9cd1ae
commit
bbd0d2b3a3
Binary file not shown.
After Width: | Height: | Size: 6.5 MiB |
@ -0,0 +1,81 @@
|
||||
# LeetCode 第 34 号问题:在排序数组中查找元素的第一个和最后一个位置
|
||||
|
||||
|
||||
题目来源于 LeetCode 上第 34 号问题:find-first-and-last-position-of-element-in-sorted-array。题目难度为 中等。
|
||||
|
||||
### 题目描述
|
||||
|
||||
给定一个按照升序排列的整数数组 **nums**,和一个目标值 **target**。找出给定目标值在数组中的开始位置和结束位置。
|
||||
|
||||
你的算法时间复杂度必须是 **O(log n)** 级别。
|
||||
|
||||
如果数组中不存在目标值,返回 [-1, -1]。
|
||||
|
||||
|
||||
**示例:**
|
||||
|
||||
```
|
||||
输入: nums = [5,7,7,8,8,10], target = 8
|
||||
输出: [3,4]
|
||||
```
|
||||
```
|
||||
输入: nums = [5,7,7,8,8,10], target = 6
|
||||
输出: [-1,-1]
|
||||
```
|
||||
### 题目解析
|
||||
|
||||
题目中要求了时间复杂度为O(log n),这就很清楚要使用二分查找法了。
|
||||
|
||||
首先定义两个指针变量,分别存储左右两个位置的索引。首先去找目标值的最左面的索引,通过循环为了防止元素丢失,每次保留最右面的元素,左侧的指针移动时+1。在循环结束的时候判断一下数组中是否包括目标值,不包括的话直接退出。
|
||||
右面的跟左侧相同,只不过正好相反。
|
||||
|
||||
|
||||
|
||||
### 动画描述
|
||||
|
||||
![](..\Animation\在排序数组中查找元素的第一个和最后一个位置.gif)
|
||||
|
||||
### 代码实现
|
||||
|
||||
```java
|
||||
// 34. 下一个排列
|
||||
// https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
|
||||
// 时间复杂度:O(n)
|
||||
// 空间复杂度:O(1)
|
||||
class Solution {
|
||||
public int[] searchRange(int[] nums, int target) {
|
||||
int[] res = new int[] { -1, -1 };
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
int l = left;
|
||||
int r = right;
|
||||
while (left < right) {
|
||||
int mid = (left + right) / 2;
|
||||
if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
}
|
||||
if (left>right||nums[left]!=target) {
|
||||
return new int[]{-1,-1};
|
||||
}
|
||||
while (l < r) {
|
||||
int mid = (l + r) / 2 + 1;
|
||||
if (nums[mid] > target) {
|
||||
r = mid - 1;
|
||||
} else {
|
||||
l = mid;
|
||||
}
|
||||
}
|
||||
if (left > right || left > r) {
|
||||
return new int[] { -1, -1 };
|
||||
} else {
|
||||
return new int[] { left, r };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
![](../../Pictures/qrcode.jpg)
|
33
0034-find-first-and-last-position-of-element-in-sorted-array/Code/1.java
Executable file
33
0034-find-first-and-last-position-of-element-in-sorted-array/Code/1.java
Executable file
@ -0,0 +1,33 @@
|
||||
class Solution {
|
||||
public int[] searchRange(int[] nums, int target) {
|
||||
int[] res = new int[] { -1, -1 };
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
int l = left;
|
||||
int r = right;
|
||||
while (left < right) {
|
||||
int mid = (left + right) / 2;
|
||||
if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
}
|
||||
if (left>right||nums[left]!=target) {
|
||||
return new int[]{-1,-1};
|
||||
}
|
||||
while (l < r) {
|
||||
int mid = (l + r) / 2 + 1;
|
||||
if (nums[mid] > target) {
|
||||
r = mid - 1;
|
||||
} else {
|
||||
l = mid;
|
||||
}
|
||||
}
|
||||
if (left > right || left > r) {
|
||||
return new int[] { -1, -1 };
|
||||
} else {
|
||||
return new int[] { left, r };
|
||||
}
|
||||
}
|
||||
}
|
BIN
0035-search-insert-position/Animation/~$搜索插入位置.pptx
Executable file
BIN
0035-search-insert-position/Animation/~$搜索插入位置.pptx
Executable file
Binary file not shown.
BIN
0035-search-insert-position/Animation/二分查找.gif
Executable file
BIN
0035-search-insert-position/Animation/二分查找.gif
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.9 MiB |
BIN
0035-search-insert-position/Animation/二分查找.mp4
Executable file
BIN
0035-search-insert-position/Animation/二分查找.mp4
Executable file
Binary file not shown.
BIN
0035-search-insert-position/Animation/暴力查找.gif
Executable file
BIN
0035-search-insert-position/Animation/暴力查找.gif
Executable file
Binary file not shown.
After Width: | Height: | Size: 2.4 MiB |
BIN
0035-search-insert-position/Animation/暴力查找.mp4
Executable file
BIN
0035-search-insert-position/Animation/暴力查找.mp4
Executable file
Binary file not shown.
113
0035-search-insert-position/Article/0035-search-insert-position.md
Executable file
113
0035-search-insert-position/Article/0035-search-insert-position.md
Executable file
@ -0,0 +1,113 @@
|
||||
# LeetCode 第 35 号问题:搜索插入位置
|
||||
|
||||
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
|
||||
>
|
||||
> 同步博客:https://www.algomooc.com
|
||||
|
||||
题目来源于 LeetCode 第 35 号问题:搜索插入位置.
|
||||
|
||||
## 题目
|
||||
|
||||
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
|
||||
你可以假设数组中无重复元素。
|
||||
|
||||
|
||||
示例 1:
|
||||
|
||||
```
|
||||
输入: [1,3,5,6], 5
|
||||
输出: 2
|
||||
```
|
||||
|
||||
示例 2:
|
||||
|
||||
|
||||
```
|
||||
输入: [1,3,5,6], 2
|
||||
输出: 1
|
||||
```
|
||||
|
||||
示例 3:
|
||||
|
||||
|
||||
```
|
||||
输入: [1,3,5,6], 7
|
||||
输出: 4
|
||||
```
|
||||
|
||||
|
||||
示例 4:
|
||||
|
||||
|
||||
```
|
||||
输入: [1,3,5,6], 0
|
||||
输出: 0
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 思路解析
|
||||
|
||||
### 暴力循环法
|
||||
|
||||
这个题看起来就是很简单的,就是一道考验查找算法的题目。最简单的就是暴力查找了。
|
||||
|
||||
#### 思路
|
||||
|
||||
遍历这个数组,然后如果当前值和目标值target一致或小于目标值target,那么就return 当前下标。这种解法的时间复杂度是O(N)
|
||||
|
||||
### 动画理解
|
||||
|
||||
![](../Animation/暴力查找.gif)
|
||||
|
||||
#### 代码实现
|
||||
|
||||
|
||||
```java
|
||||
//时间复杂度:O(n)
|
||||
//空间复杂度:O(1)
|
||||
class Solution {
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
int i=0;
|
||||
for(;i<nums.length;i++){
|
||||
if (nums[i]>=target){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 二分法
|
||||
|
||||
#### 思路
|
||||
|
||||
除了暴力法,我们在排序数组中查找值还可以用的一种方法是二分法,思路还是和改良的暴力循环法一样,先找到左右边界,然后计算,每次可以省出一半的时间。时间复杂度为O(logn)
|
||||
|
||||
#### 代码实现
|
||||
|
||||
```java
|
||||
//时间复杂度:O(lon(n))
|
||||
//空间复杂度:O(1)
|
||||
class Solution {
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
if (target>nums[nums.length-1]) {
|
||||
return nums.length;
|
||||
}
|
||||
int left=0;
|
||||
int right=nums.length-1;
|
||||
while (left < right) {
|
||||
int mid = (left + right) / 2;
|
||||
if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
![](../../Pictures/qrcode.jpg)
|
11
0035-search-insert-position/Code/1.java
Executable file
11
0035-search-insert-position/Code/1.java
Executable file
@ -0,0 +1,11 @@
|
||||
class Solution1 {
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
int i=0;
|
||||
for(;i<nums.length;i++){
|
||||
if (nums[i]>=target){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
21
0035-search-insert-position/Code/2.java
Executable file
21
0035-search-insert-position/Code/2.java
Executable file
@ -0,0 +1,21 @@
|
||||
//时间复杂度:O(lon(n))
|
||||
//空间复杂度:O(1)
|
||||
class Solution2 {
|
||||
public int searchInsert(int[] nums, int target) {
|
||||
if (target>nums[nums.length-1]) {
|
||||
return nums.length;
|
||||
}
|
||||
int left=0;
|
||||
int right=nums.length-1;
|
||||
while (left < right) {
|
||||
int mid = (left + right) / 2;
|
||||
if (nums[mid] < target) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
}
|
||||
}
|
||||
return left;
|
||||
|
||||
}
|
||||
}
|
BIN
0036-valid-sudoku/Animation/HashMap.gif
Executable file
BIN
0036-valid-sudoku/Animation/HashMap.gif
Executable file
Binary file not shown.
After Width: | Height: | Size: 5.7 MiB |
BIN
0036-valid-sudoku/Animation/HashMap.mp4
Executable file
BIN
0036-valid-sudoku/Animation/HashMap.mp4
Executable file
Binary file not shown.
134
0036-valid-sudoku/Article/0036-valid-sudoku.md
Executable file
134
0036-valid-sudoku/Article/0036-valid-sudoku.md
Executable file
@ -0,0 +1,134 @@
|
||||
# LeetCode 第 36 号问题:有效的数独
|
||||
|
||||
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
|
||||
>
|
||||
> 同步博客:https://www.algomooc.com
|
||||
|
||||
题目来源于 LeetCode 第 36 号问题:有效的数独.
|
||||
|
||||
## 题目
|
||||
|
||||
判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。
|
||||
|
||||
|
||||
数字 1-9 在每一行只能出现一次。
|
||||
数字 1-9 在每一列只能出现一次。
|
||||
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
|
||||
|
||||
|
||||
示例 1:
|
||||
|
||||
```
|
||||
输入:
|
||||
[
|
||||
["5","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]
|
||||
]
|
||||
输出: true
|
||||
```
|
||||
|
||||
示例 2:
|
||||
|
||||
|
||||
```
|
||||
输入:
|
||||
[
|
||||
["8","3",".",".","7",".",".",".","."],
|
||||
["6",".",".","1","9","5",".",".","."],
|
||||
[".","9","8",".",".",".",".","6","."],
|
||||
["8",".",".",".","6",".",".",".","3"],
|
||||
["4",".",".","8",".","3",".",".","1"],
|
||||
["7",".",".",".","2",".",".",".","6"],
|
||||
[".","6",".",".",".",".","2","8","."],
|
||||
[".",".",".","4","1","9",".",".","5"],
|
||||
[".",".",".",".","8",".",".","7","9"]
|
||||
]
|
||||
输出: false
|
||||
解释: 除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
|
||||
但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
|
||||
```
|
||||
|
||||
示例 3:
|
||||
|
||||
|
||||
```
|
||||
输入: [1,3,5,6], 7
|
||||
输出: 4
|
||||
```
|
||||
|
||||
|
||||
示例 4:
|
||||
|
||||
|
||||
```
|
||||
输入: [1,3,5,6], 0
|
||||
输出: 0
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 思路解析
|
||||
|
||||
### 一次遍历法
|
||||
|
||||
#### 思路
|
||||
|
||||
这道题因为需要判断数值是否存在,所以用Hash Map是一个很好的选择。
|
||||
因为每一行、每一列、每一格都是需要单独进行判断的,所以需要建立三个长度为9的HashMap数组,分别存放行、列、格的数值。
|
||||
|
||||
通过一个二层循环遍历这个9*9的数组,把当前格的数值存放到对应的HashMap中,判断之前是否已经存放过了,如果已经存放过那就退出,返回false,如果是.的话那就跳过,这样只需要遍历一边就可以了。
|
||||
|
||||
### 动画理解
|
||||
|
||||
![](../Animation/HashMap.gif)
|
||||
|
||||
#### 代码实现
|
||||
|
||||
|
||||
```java
|
||||
//时间复杂度:O(n)
|
||||
//空间复杂度:O(1)
|
||||
class Solution {
|
||||
public boolean isValidSudoku(char[][] board) {
|
||||
HashMap[] row = new HashMap[9];
|
||||
HashMap[] column = new HashMap[9];
|
||||
HashMap[] box = new HashMap[9];
|
||||
for (int i = 0; i < 9; i++) {
|
||||
row[i] = new HashMap(9);
|
||||
column[i] = new HashMap(9);
|
||||
box[i] = new HashMap(9);
|
||||
}
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
if (board[i][j] == '.') {
|
||||
continue;
|
||||
}
|
||||
int boxIndex=i / 3 * 3 + j / 3;
|
||||
if ((boolean) row[i].getOrDefault(board[i][j], true)) {
|
||||
return false;
|
||||
}
|
||||
if ((boolean) column[j].getOrDefault(board[i][j], true)) {
|
||||
return false;
|
||||
}
|
||||
if ((boolean) box[boxIndex].getOrDefault(board[i][j], true)) {
|
||||
return false;
|
||||
}
|
||||
row[i].put(board[i][j], false);
|
||||
column[j].put(board[i][j], false);
|
||||
box[boxIndex].put(board[i][j], false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
![](../../Pictures/qrcode.jpg)
|
34
0036-valid-sudoku/Code/1.java
Executable file
34
0036-valid-sudoku/Code/1.java
Executable file
@ -0,0 +1,34 @@
|
||||
class Solution {
|
||||
public boolean isValidSudoku(char[][] board) {
|
||||
HashMap[] row = new HashMap[9];
|
||||
HashMap[] column = new HashMap[9];
|
||||
HashMap[] box = new HashMap[9];
|
||||
for (int i = 0; i < 9; i++) {
|
||||
row[i] = new HashMap(9);
|
||||
column[i] = new HashMap(9);
|
||||
box[i] = new HashMap(9);
|
||||
}
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
if (board[i][j] == '.') {
|
||||
continue;
|
||||
}
|
||||
int boxIndex=i / 3 * 3 + j / 3;
|
||||
if ((boolean) row[i].getOrDefault(board[i][j], true)) {
|
||||
return false;
|
||||
}
|
||||
if ((boolean) column[j].getOrDefault(board[i][j], true)) {
|
||||
return false;
|
||||
}
|
||||
if ((boolean) box[boxIndex].getOrDefault(board[i][j], true)) {
|
||||
return false;
|
||||
}
|
||||
row[i].put(board[i][j], false);
|
||||
column[j].put(board[i][j], false);
|
||||
box[boxIndex].put(board[i][j], false);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user