Skip to content

Commit 5e36d57

Browse files
Merge branch 'master' into master
2 parents 3dcaa43 + 9214930 commit 5e36d57

8 files changed

+236
-12
lines changed

problems/0034.在排序数组中查找元素的第一个和最后一个位置.md

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
如果数组中不存在目标值 target,返回 [-1, -1]
1515

1616
进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
17-
 
17+
1818

1919
示例 1:
2020
* 输入:nums = [5,7,7,8,8,10], target = 8
@@ -173,8 +173,105 @@ private:
173173
## Java
174174
175175
```java
176+
class Solution {
177+
int[] searchRange(int[] nums, int target) {
178+
int leftBorder = getLeftBorder(nums, target);
179+
int rightBorder = getRightBorder(nums, target);
180+
// 情况一
181+
if (leftBorder == -2 || rightBorder == -2) return new int[]{-1, -1};
182+
// 情况三
183+
if (rightBorder - leftBorder > 1) return new int[]{leftBorder + 1, rightBorder - 1};
184+
// 情况二
185+
return new int[]{-1, -1};
186+
}
187+
188+
int getRightBorder(int[] nums, int target) {
189+
int left = 0;
190+
int right = nums.length - 1;
191+
int rightBorder = -2; // 记录一下rightBorder没有被赋值的情况
192+
while (left <= right) {
193+
int middle = left + ((right - left) / 2);
194+
if (nums[middle] > target) {
195+
right = middle - 1;
196+
} else { // 寻找右边界,nums[middle] == target的时候更新left
197+
left = middle + 1;
198+
rightBorder = left;
199+
}
200+
}
201+
return rightBorder;
202+
}
203+
204+
int getLeftBorder(int[] nums, int target) {
205+
int left = 0;
206+
int right = nums.length - 1;
207+
int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
208+
while (left <= right) {
209+
int middle = left + ((right - left) / 2);
210+
if (nums[middle] >= target) { // 寻找左边界,nums[middle] == target的时候更新right
211+
right = middle - 1;
212+
leftBorder = right;
213+
} else {
214+
left = middle + 1;
215+
}
216+
}
217+
return leftBorder;
218+
}
219+
}
176220
```
177221

222+
```java
223+
// 解法2
224+
// 1、首先,在 nums 数组中二分查找 target;
225+
// 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
226+
// 3、如果二分查找失败,则 binarySearch 返回 nums 中 为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
227+
228+
class Solution {
229+
public int[] searchRange(int[] nums, int target) {
230+
int index = binarySearch(nums, target); // 二分查找
231+
232+
if (index == -1) { // nums 中不存在 target,直接返回 {-1, -1}
233+
return new int[] {-1, -1}; // 匿名数组
234+
}
235+
// nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
236+
int left = index;
237+
int right = index;
238+
// 向左滑动,找左边界
239+
while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
240+
left--;
241+
}
242+
// 向左滑动,找右边界
243+
while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。
244+
right++;
245+
}
246+
return new int[] {left, right};
247+
}
248+
249+
/**
250+
* 二分查找
251+
* @param nums
252+
* @param target
253+
*/
254+
public int binarySearch(int[] nums, int target) {
255+
int left = 0;
256+
int right = nums.length - 1; // 不变量:左闭右闭区间
257+
258+
while (left <= right) { // 不变量:左闭右闭区间
259+
int mid = left + (right - left) / 2;
260+
if (nums[mid] == target) {
261+
return mid;
262+
} else if (nums[mid] < target) {
263+
left = mid + 1;
264+
} else {
265+
right = mid - 1; // 不变量:左闭右闭区间
266+
}
267+
}
268+
return -1; // 不存在
269+
}
270+
}
271+
```
272+
273+
274+
178275
## Python
179276

180277
```python
@@ -196,4 +293,3 @@ private:
196293
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
197294
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
198295

199-

problems/0141.环形链表.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
1515

1616
如果链表中存在环,则返回 true 。 否则,返回 false 。
17-
 
17+
1818
![](https://code-thinking-1253855093.file.myqcloud.com/pics/20210727173600.png)
1919

2020
# 思路
@@ -74,6 +74,21 @@ public:
7474
## Java
7575
7676
```java
77+
public class Solution {
78+
public boolean hasCycle(ListNode head) {
79+
ListNode fast = head;
80+
ListNode slow = head;
81+
// 空链表、单节点链表一定不会有环
82+
while (fast != null && fast.next != null) {
83+
fast = fast.next.next; // 快指针,一次移动两步
84+
slow = slow.next; // 慢指针,一次移动一步
85+
if (fast == slow) { // 快慢指针相遇,表明有环
86+
return true;
87+
}
88+
}
89+
return false; // 正常走到链表末尾,表明没有环
90+
}
91+
}
7792
```
7893

7994
## Python

problems/0203.移除链表元素.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,39 @@ public:
146146
147147
148148
## 其他语言版本
149+
C:
150+
```c
151+
/**
152+
* Definition for singly-linked list.
153+
* struct ListNode {
154+
* int val;
155+
* struct ListNode *next;
156+
* };
157+
*/
149158
150159
160+
struct ListNode* removeElements(struct ListNode* head, int val){
161+
typedef struct ListNode ListNode;
162+
ListNode *shead;
163+
shead = (ListNode *)malloc(sizeof(ListNode));
164+
shead->next = head;
165+
ListNode *cur = shead;
166+
while(cur->next != NULL){
167+
if (cur->next->val == val){
168+
ListNode *tmp = cur->next;
169+
cur->next = cur->next->next;
170+
free(tmp);
171+
}
172+
else{
173+
cur = cur->next;
174+
}
175+
}
176+
head = shead->next;
177+
free(shead);
178+
return head;
179+
}
180+
```
181+
151182
Java:
152183
```java
153184
/**

problems/0283.移动零.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,21 @@ public:
6464
6565
Java:
6666
67+
```java
68+
public void moveZeroes(int[] nums) {
69+
int slow = 0;
70+
for (int fast = 0; fast < nums.length; fast++) {
71+
if (nums[fast] != 0) {
72+
nums[slow++] = nums[fast];
73+
}
74+
}
75+
// 后面的元素全变成 0
76+
for (int j = slow; j < nums.length; j++) {
77+
nums[j] = 0;
78+
}
79+
}
80+
```
81+
6782
Python:
6883

6984
```python

problems/0435.无重叠区间.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,29 @@ class Solution {
211211
}
212212
```
213213

214+
Java:
215+
按左边排序,不管右边顺序。相交的时候取最小的右边。
216+
```java
217+
class Solution {
218+
public int eraseOverlapIntervals(int[][] intervals) {
219+
220+
Arrays.sort(intervals,(a,b)->{
221+
return Integer.compare(a[0],b[0]);
222+
});
223+
int remove = 0;
224+
int pre = intervals[0][1];
225+
for(int i=1;i<intervals.length;i++){
226+
if(pre>intervals[i][0]) {
227+
remove++;
228+
pre = Math.min(pre,intervals[i][1]);
229+
}
230+
else pre = intervals[i][1];
231+
}
232+
return remove;
233+
}
234+
}
235+
```
236+
214237
Python:
215238
```python
216239
class Solution:

problems/0941.有效的山脉数组.md

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ https://leetcode-cn.com/problems/valid-mountain-array/
1818

1919
C++代码如下:
2020

21-
```
21+
```c++
2222
class Solution {
2323
public:
2424
bool validMountainArray(vector<int>& A) {
@@ -38,6 +38,33 @@ public:
3838
}
3939
};
4040
```
41-
如果想系统学一学双指针的话, 可以看一下这篇[双指针法:总结篇!](https://mp.weixin.qq.com/s/_p7grwjISfMh0U65uOyCjA)
41+
Java 版本如下:
42+
43+
```java
44+
class Solution {
45+
public boolean validMountainArray(int[] arr) {
46+
if (arr.length < 3) { // 此时,一定不是有效的山脉数组
47+
return false;
48+
}
49+
// 双指针
50+
int left = 0;
51+
int right = arr.length - 1;
52+
// 注意防止指针越界
53+
while (left + 1 < arr.length && arr[left] < arr[left + 1]) {
54+
left++;
55+
}
56+
// 注意防止指针越界
57+
while (right > 0 && arr[right] < arr[right - 1]) {
58+
right--;
59+
}
60+
// 如果left或者right都在起始位置,说明不是山峰
61+
if (left == right && left != 0 && right != arr.length - 1) {
62+
return true;
63+
}
64+
return false;
65+
}
66+
}
67+
```
4268

69+
如果想系统学一学双指针的话, 可以看一下这篇[双指针法:总结篇!](https://mp.weixin.qq.com/s/_p7grwjISfMh0U65uOyCjA)
4370

problems/1207.独一无二的出现次数.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,28 @@ public:
7777
7878
Java:
7979
80+
```java
81+
class Solution {
82+
public boolean uniqueOccurrences(int[] arr) {
83+
int[] count = new int[2002];
84+
for (int i = 0; i < arr.length; i++) {
85+
count[arr[i] + 1000]++; // 防止负数作为下标
86+
}
87+
boolean[] flag = new boolean[1002]; // 标记相同频率是否重复出现
88+
for (int i = 0; i <= 2000; i++) {
89+
if (count[i] > 0) {
90+
if (flag[count[i]] == false) {
91+
flag[count[i]] = true;
92+
} else {
93+
return false;
94+
}
95+
}
96+
}
97+
return true;
98+
}
99+
}
100+
```
101+
80102
Python:
81103

82104
Go:
@@ -89,4 +111,3 @@ JavaScript:
89111
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
90112
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
91113

92-

problems/剑指Offer58-II.左旋转字符串.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,10 @@ func reverse(b []byte, left, right int){
164164
}
165165
```
166166

167-
JavaScript版本
167+
168+
JavaScript:
168169

169170
```javascript
170-
/**
171-
* @param {string} s
172-
* @param {number} n
173-
* @return {string}
174-
*/
175171
var reverseLeftWords = function (s, n) {
176172
const reverse = (str, left, right) => {
177173
let strArr = str.split("");

0 commit comments

Comments
 (0)