Skip to content

Commit 1b247df

Browse files
committed
2 parents 9103e43 + b553da6 commit 1b247df

File tree

5 files changed

+217
-32
lines changed

5 files changed

+217
-32
lines changed

animation-simulation/剑指offer/1的个数.md

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
>
55
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
66
>
7-
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
7+
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
88
99
今天我们来看一道贼棒的题目,题目不长,很经典,也很容易理解,我们一起来看一哈吧,
1010

@@ -87,7 +87,7 @@
8787

8888
那我们将**当前位左边的定义为高位****当前位右边的定义位低位**
8989

90-
> 例:n = 1004 ,此时指针指向十位(当前位)num = 10,高位为百位,千位,低位为个位
90+
> 例:n = 1004 ,此时指针指向十位(当前位)num = 10,高位为百位,千位,低位为个位
9191
9292
而且我们某一位的取值范围为 0 ~ 9,那么我们可以将这 10 个数分为 3 类,小于 1 (当前位数字为 0 ),等于 1(当前位数字为 1 ) ,大于 1(当前位上数字为 2 ~ 9),下面我们就来分别考虑三种情况。
9393

@@ -139,7 +139,7 @@
139139
140140
可以继续想到密码盘,求第二段时,把前 3 位固定,只能改变最后一位。最后一位最大能到 4 ,那么共有几种情况?
141141

142-
### n = 1024
142+
### n = 1024
143143

144144
我们想要计算出**小于等于 1024 的非负整数中**,十位上出现 1 的次数。
145145

@@ -187,12 +187,12 @@ class Solution {
187187
while (high != 0 || cur != 0) {
188188
cur = high % 10;
189189
high /= 10;
190-
//这里我们可以提出 high * num 因为我们发现无论为几,都含有它
190+
//这里我们可以提出 high * num 因为我们发现无论为几,都含有它
191191
if (cur == 0) count += high * num;
192-
else if (cur == 1) count += high * num + 1 + low;
192+
else if (cur == 1) count += high * num + 1 + low;
193193
else count += (high + 1) * num;
194194
//低位
195-
low = cur * num + low;
195+
low = cur * num + low;
196196
num *= 10;
197197
}
198198
return count;
@@ -209,10 +209,10 @@ class Solution {
209209
while high != 0 || cur != 0 {
210210
cur = high % 10
211211
high /= 10
212-
//这里我们可以提出 high * num 因为我们发现无论为几,都含有它
212+
//这里我们可以提出 high * num 因为我们发现无论为几,都含有它
213213
if cur == 0 {
214214
count += high * num
215-
} else if cur == 1 {
215+
} else if cur == 1 {
216216
count += high * num + 1 + low
217217
} else {
218218
count += (high + 1) * num
@@ -227,5 +227,37 @@ class Solution {
227227

228228
时间复杂度 : O(logn) 空间复杂度 O(1)
229229

230-
231-
230+
C++ Code:
231+
232+
```C++
233+
class Solution
234+
{
235+
public:
236+
int countDigitOne(int n)
237+
{
238+
// 高位, 低位, 当前位
239+
int high = n, low = 0, cur = 0;
240+
int count = 0, num = 1;
241+
242+
//数字是0的时候完全没必要继续计算
243+
while (high != 0)
244+
{
245+
cur = high % 10;
246+
high /= 10;
247+
//这里我们可以提出 high * num 因为我们发现无论为几,都含有它
248+
if (cur == 0)
249+
count += (high * num);
250+
else if (cur == 1)
251+
count += (high * num + 1 + low);
252+
else
253+
count += ((high + 1) * num);
254+
//低位
255+
low = cur * num + low;
256+
//提前检查剩余数字, 以免溢出
257+
if (high != 0)
258+
num *= 10;
259+
}
260+
return count;
261+
}
262+
};
263+
```

animation-simulation/数组篇/leetcode1052爱生气的书店老板.md

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
>
55
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
66
>
7-
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
7+
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
88
99
#### [1052. 爱生气的书店老板](https://leetcode-cn.com/problems/grumpy-bookstore-owner/)
1010

@@ -48,7 +48,7 @@ rightsum 是窗口右区间的值,和左区间加和方式一样。那么我
4848

4949
我们此时移动了窗口,
5050

51-
则左半区间范围扩大,但是 leftsum 的值没有变,这时因为新加入的值,所对应的 grumpy[i] == 1,所以其值不会发生改变,因为我们只统计 grumpy[i] == 0 的值,
51+
则左半区间范围扩大,但是 leftsum 的值没有变,这时因为新加入的值,所对应的 grumpy[i] == 1,所以其值不会发生改变,因为我们只统计 grumpy[i] == 0 的值,
5252

5353
右半区间范围减少,rightsum 值也减少,因为右半区间减小的值,其对应的 grumpy[i] == 0,所以 rightsum -= grumpy[i]
5454

@@ -72,15 +72,15 @@ class Solution {
7272
}
7373
}
7474
//窗口的值
75-
for (int i = 0; i < X; ++i) {
76-
winsum += customers[i];
75+
for (int i = 0; i < X; ++i) {
76+
winsum += customers[i];
7777
}
7878
int leftsum = 0;
7979
//窗口左边缘
8080
int left = 1;
8181
//窗口右边缘
8282
int right = X;
83-
int maxcustomer = winsum + leftsum + rightsum;
83+
int maxcustomer = winsum + leftsum + rightsum;
8484
while (right < customers.length) {
8585
//重新计算左区间的值,也可以用 customer 值和 grumpy 值相乘获得
8686
if (grumpy[left-1] == 0) {
@@ -97,7 +97,7 @@ class Solution {
9797
//移动窗口
9898
left++;
9999
right++;
100-
}
100+
}
101101
return maxcustomer;
102102
}
103103
}
@@ -151,8 +151,54 @@ class Solution {
151151
left += 1
152152
right += 1
153153
}
154-
154+
155155
return maxCustomer
156156
}
157157
}
158158
```
159+
160+
C++ Code
161+
162+
```C++
163+
class Solution
164+
{
165+
public:
166+
int maxSatisfied(vector<int> &customers, vector<int> &grumpy, int minutes)
167+
{
168+
for_each(grumpy.begin(), grumpy.end(), [](auto &g){ g = !g; });
169+
vector<int> osum(customers.size(), 0);
170+
171+
//先初始化第一个元素
172+
osum[0] = customers[0] * grumpy[0];
173+
//计算前缀和, osum是origin sum
174+
for (int i = 1; i < osum.size(); i++)
175+
{
176+
osum[i] = osum[i - 1] + customers[i] * grumpy[i];
177+
}
178+
179+
//计算连续minutes的和
180+
vector<int> msum(customers.size() - minutes + 1, 0);
181+
for (int i = 0; i < minutes; i++)
182+
{
183+
msum[0] += customers[i];
184+
}
185+
for (int i = 1; i < msum.size(); i++)
186+
{
187+
msum[i] = msum[i - 1] - customers[i - 1] + customers[i + minutes - 1];
188+
}
189+
190+
//分成三段计算
191+
int result = 0;
192+
for (int i = 0; i < msum.size(); i++)
193+
{
194+
//左 中 右
195+
//注意左的边界条件, 可以使用边界测试
196+
int sum = ((i - 1 >= 0) ? osum[i - 1] : 0) + msum[i] + osum[osum.size() - 1] - osum[i + minutes - 1];
197+
if (sum > result)
198+
result = sum;
199+
}
200+
201+
return result;
202+
}
203+
};
204+
```

animation-simulation/数组篇/leetcode41缺失的第一个正数.md

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
>
33
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
44
>
5-
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
5+
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
66
77
#### [41. 缺失的第一个正数](https://leetcode-cn.com/problems/first-missing-positive/)
88

@@ -53,15 +53,15 @@ class Solution {
5353
for (int x : nums) {
5454
if (x > 0 && x < res.length) {
5555
res[x] = x;
56-
}
56+
}
5757
}
5858
//遍历查找,发现不一样时直接返回
5959
for (int i = 1; i < res.length; i++) {
6060
if (res[i] != i) {
6161
return i;
62-
}
62+
}
6363
}
64-
//缺少最后一个,例如 1,2,3此时缺少 4 ,细节2
64+
//缺少最后一个,例如 1,2,3此时缺少 4 ,细节2
6565
return res.length;
6666
}
6767
}
@@ -85,7 +85,7 @@ class Solution:
8585
for i in range(1, len(res)):
8686
if res[i] != i:
8787
return i
88-
# 缺少最后一个,例如 1,2,3此时缺少 4 ,细节2
88+
# 缺少最后一个,例如 1,2,3此时缺少 4 ,细节2
8989
return len(res)
9090
```
9191

@@ -145,7 +145,7 @@ class Solution {
145145
for (int i = 0; i < len; ++i) {
146146
//需要考虑指针移动情况,大于0,小于len+1,不等与i+1,两个交换的数相等时,防止死循环
147147
while (nums[i] > 0 && nums[i] < len + 1 && nums[i] != i+1 && nums[i] != nums[nums[i]-1]) {
148-
swap(nums,i,nums[i] - 1);
148+
swap(nums,i,nums[i] - 1);
149149
}
150150
}
151151
//遍历寻找缺失的正整数
@@ -207,10 +207,10 @@ class Solution {
207207
for i in 0..<len {
208208
// 需要考虑指针移动情况,大于0,小于len+1,不等与i+1,
209209
// 两个交换的数相等时,防止死循环
210-
while nums[i] > 0
211-
&& nums[i] < len + 1
210+
while nums[i] > 0
211+
&& nums[i] < len + 1
212212
&& nums[i] != i + 1
213-
&& nums[i] != nums[nums[i] - 1]
213+
&& nums[i] != nums[nums[i] - 1]
214214
{
215215
//nums.swapAt(i, (nums[i] - 1)) // 系统方法
216216
self.swap(&nums, i, (nums[i] - 1)) // 自定义方法
@@ -232,3 +232,44 @@ class Solution {
232232
}
233233
}
234234
```
235+
236+
C++ Code
237+
238+
```C++
239+
class Solution
240+
{
241+
public:
242+
int firstMissingPositive(vector<int> &nums)
243+
{
244+
int size = nums.size();
245+
//判断范围是否符合要求
246+
auto inRange = [](auto s, auto e)
247+
{
248+
return [s, e](auto &n)
249+
{
250+
return e >= n && n >= s;
251+
};
252+
};
253+
auto cusInRange = inRange(1, size);
254+
//增加数组长度, 便于计算, 不需要再转换
255+
nums.push_back(0);
256+
257+
for (int i = 0; i < size; i++)
258+
{
259+
//将不在正确位置的元素放到正确位置上
260+
while (cusInRange(nums[i]) && nums[i] != i && nums[nums[i]] != nums[i])
261+
{
262+
swap(nums[i], nums[nums[i]]);
263+
}
264+
}
265+
266+
//找出缺失的元素
267+
for (int i = 1; i <= size; i++)
268+
{
269+
if (nums[i] != i)
270+
return i;
271+
}
272+
return size + 1;
273+
}
274+
};
275+
```

animation-simulation/数组篇/leetcode485最大连续1的个数.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
>
33
> 感谢支持,该仓库会一直维护,希望对各位有一丢丢帮助。
44
>
5-
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
5+
> 另外希望手机阅读的同学可以来我的 <u>[**公众号:袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
66
77
#### [485. 最大连续 1 的个数](https://leetcode-cn.com/problems/max-consecutive-ones/)
88

@@ -16,7 +16,7 @@
1616
1717
我的这个方法比较奇怪,但是效率还可以,战胜了 100% , 尽量减少了 Math.max()的使用,我们来看一下具体思路,利用 right 指针进行探路,如果遇到 1 则继续走,遇到零时则停下,求当前 1 的个数。
1818

19-
这时我们可以通过 right - left 得到 1 的 个数,因为此时我们的 right 指针指在 0 处,所以不需要和之前一样通过 right - left + 1 获得窗口长度。
19+
这时我们可以通过 right - left 得到 1 的 个数,因为此时我们的 right 指针指在 0 处,所以不需要和之前一样通过 right - left + 1 获得窗口长度。
2020

2121
然后我们再使用 while 循环,遍历完为 0 的情况,跳到下一段为 1 的情况,然后移动 left 指针。 left = right,站在同一起点,继续执行上诉过程。
2222

@@ -125,7 +125,7 @@ class Solution {
125125

126126
int count = 0;
127127
int maxcount = 0;
128-
128+
129129
for (int i = 0; i < nums.length; ++i) {
130130
if (nums[i] == 1) {
131131
count++;
@@ -172,8 +172,43 @@ class Solution {
172172
maxCount = max(maxCount, count)
173173
count = 0
174174
}
175-
}
175+
}
176176
return max(maxCount, count)
177177
}
178178
}
179179
```
180+
181+
C++ Code
182+
183+
```C++
184+
class Solution
185+
{
186+
public:
187+
int findMaxConsecutiveOnes(vector<int> &nums)
188+
{
189+
int s = 0;
190+
int e = 0;
191+
int result = 0;
192+
int size = nums.size();
193+
194+
while (s < size && e < size)
195+
{
196+
while (s < size && nums[s++] == 1)
197+
{
198+
e = s;
199+
while (e < size && nums[e] == 1)
200+
{
201+
e++;
202+
};
203+
//注意需要加1, 可以使用极限条件测试
204+
int r = e - s + 1;
205+
if (r > result)
206+
result = r;
207+
s = e;
208+
}
209+
}
210+
211+
return result;
212+
}
213+
};
214+
```

0 commit comments

Comments
 (0)