Skip to content

Commit 7b6d612

Browse files
committed
2.28
1 parent cd4410e commit 7b6d612

10 files changed

+406
-1
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@
5252

5353
- [字符串的排列](./SwordToOffer/Doc/字符串的排列.md)
5454

55-
55+
- [***数组中出现次数超过一半的数字***](./SwordToOffer/Doc/数组中出现次数超过一半的数字.md)
56+
57+
- [最小的K个数](./SwordToOffer/Doc/最小的K个数.md)
5658

59+
- [连续子数组的最大和](./SwordToOffer/Doc/连续子数组的最大和.md)
5760

61+
- [把数组排成最小的数](./SwordToOffer/Doc/把数组排成最小的数.md)
5862

63+

SwordToOffer/Code/27.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- coding:utf-8 -*-
2+
class Solution:
3+
def MoreThanHalfNum_Solution(self, numbers):
4+
# write code here
5+
if numbers is None:
6+
return 0
7+
8+
size = len(numbers)
9+
10+
if size == 0:
11+
return 0
12+
if size == 1:
13+
return numbers
14+
15+
soldier = numbers[0]
16+
soldierCount = 1
17+
soldierIndex = 0
18+
flag = False
19+
for i in range(1, size):
20+
if numbers[i] != soldier:
21+
soldierCount -= 1
22+
if soldierCount == 0:
23+
soldierIndex += 1
24+
soldier = numbers[soldierIndex]
25+
soldierCount = 1
26+
flag = False
27+
else:
28+
flag = True
29+
soldierCount += 1
30+
31+
if soldierCount > 1:
32+
return soldier
33+
elif soldierCount == 1 and flag:
34+
return soldier
35+
else:
36+
return 0
37+
38+
39+
s = Solution()
40+
print s.MoreThanHalfNum_Solution([1])

SwordToOffer/Code/28.py

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# -*- coding:utf-8 -*-
2+
class Solution:
3+
4+
def siftUp(self, a, index):
5+
6+
while (True):
7+
if index == 1:
8+
return a
9+
parentIndex = int(index / 2)
10+
if a[parentIndex] < a[index]:
11+
t = a[parentIndex]
12+
a[parentIndex] = a[index]
13+
a[index] = t
14+
index = parentIndex
15+
else:
16+
return a
17+
18+
def siftDown(self, a, index):
19+
size = len(a) - 1
20+
while (True):
21+
index = 2 * index
22+
if index > size:
23+
return a
24+
25+
if index + 1 <= size:
26+
if a[index + 1] > a[index]:
27+
index += 1
28+
29+
if a[index] > a[int(index / 2)]:
30+
t = a[index]
31+
a[index] = a[int(index / 2)]
32+
a[int(index / 2)] = t
33+
34+
def makeHeap(self, a, k):
35+
for i in range(int(k / 2), 0, -1):
36+
a = self.siftDown(a, i)
37+
return a
38+
39+
def GetLeastNumbers_Solution(self, tinput, k):
40+
# write code here
41+
if tinput is None:
42+
return []
43+
44+
size = len(tinput)
45+
if size < k or k==0:
46+
return []
47+
48+
a = [0]
49+
a = a + tinput[0:k]
50+
a = self.makeHeap(a, k)
51+
for i in range(k, len(tinput)):
52+
if tinput[i] < a[1]:
53+
a[1] = tinput[i]
54+
a = self.siftDown(a, 1)
55+
56+
a = sorted(a[1:])
57+
58+
return a
59+
60+
61+
s = Solution()
62+
s.GetLeastNumbers_Solution([4, 5, 1, 6, 2, 7, 3, 8], 4)

SwordToOffer/Code/29.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# -*- coding:utf-8 -*-
2+
class Solution:
3+
def FindGreatestSumOfSubArray(self, array):
4+
# write code here
5+
res = array[0]
6+
f = array[0]
7+
8+
size = len(array)
9+
10+
for i in range(1, size):
11+
f = max(array[i], array[i] + f)
12+
res = max(res, f)
13+
14+
return res
15+
16+
17+
s = Solution()
18+
print s.FindGreatestSumOfSubArray([1, -2, 3, 10, -4, 7, 2, -5])

SwordToOffer/Code/30.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding:utf-8 -*-
2+
class Solution:
3+
4+
def PrintMinNumber(self, numbers):
5+
# write code here
6+
if numbers is None:
7+
return ""
8+
if len(numbers)==0:
9+
return ""
10+
strs = []
11+
for item in numbers:
12+
strs.append(str(item))
13+
14+
z = sorted(strs, cmp)
15+
16+
r=''
17+
18+
for item in z:
19+
r=r+item
20+
21+
22+
return int(r)
23+
24+
25+
def cmp(str1, str2):
26+
s1 = str1 + str2
27+
s2 = str2 + str1
28+
29+
if int(s1) < int(s2):
30+
return -1
31+
else:
32+
return 0
33+
34+
35+
s = Solution()
36+
print s.PrintMinNumber([3,32,321])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# 把数组排成最小的数
2+
3+
<center>知识点:</center>
4+
5+
6+
## 题目描述
7+
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
8+
## 解题思路
9+
10+
11+
12+
## 代码
13+
14+
[这里](../Code/n.py)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# 数组中出现次数超过一半的数字
2+
3+
<center>知识点:</center>
4+
5+
6+
## 题目描述
7+
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
8+
## 解题思路
9+
10+
11+
采用阵地攻守的思想:
12+
设置士兵soldier(初始时为第一个元素),士兵当前生命值soldierCount(每次的初始值为0),当前士兵对应的数组下标soldierIndex(起始值为0),对数组进行遍历,如果soldier与当前元素相等,则soldierCount加一,否则soldierCount减一,如果soldierCount为0,则soldierIndex增一即更新soldier的值,到最后如果soldierCount为1,则此时soldier可能为出现次数超过一半的元素,之所以可能是因为存在一种情况比如:[1,2,3],这样遍历到最后一个元素时soldier为3对应的soldierCount最后的值也是1而非0因为其初始值为1,没增也没减,解决方法是增加一个flag用来标记当前soldierCount是否增加过,如果当前soldierCount增加过但是后来由于减1减到了1则当前soldier就是出现次数超过一半的元素,否则不是。
13+
14+
## 代码
15+
```python
16+
def MoreThanHalfNum_Solution(self, numbers):
17+
# write code here
18+
if numbers is None:
19+
return 0
20+
21+
size = len(numbers)
22+
23+
if size == 0:
24+
return 0
25+
if size == 1:
26+
return numbers
27+
28+
soldier = numbers[0]
29+
soldierCount = 1
30+
soldierIndex = 0
31+
flag = False
32+
for i in range(1, size):
33+
if numbers[i] != soldier:
34+
soldierCount -= 1
35+
if soldierCount == 0:
36+
soldierIndex += 1
37+
soldier = numbers[soldierIndex]
38+
soldierCount = 1
39+
flag = False
40+
else:
41+
flag = True
42+
soldierCount += 1
43+
44+
if soldierCount > 1:
45+
return soldier
46+
elif soldierCount == 1 and flag:
47+
return soldier
48+
else:
49+
return 0
50+
```
51+
52+
[这里](../Code/27.py)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# 整数中1出现的次数(从1到n整数中出现1的次数)
2+
3+
<center>知识点:</center>
4+
5+
6+
## 题目描述
7+
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
8+
## 解题思路
9+
对每个数求出其每一位的数,与1比较并计数。
10+
11+
12+
## 代码
13+
14+
[这里](../Code/n.py)

SwordToOffer/Doc/最小的K个数.md

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# 最小的K个数
2+
3+
<center>知识点:</center>
4+
5+
6+
## 题目描述
7+
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
8+
## 解题思路
9+
10+
类似堆排序的思路,维护一个具有k个元素的大顶堆,然后将剩余n-k个数依次与堆顶比较,如果大于堆顶则跳过,否则删除堆顶,将其替换为比起小的当前数,然后调整堆为大顶堆,最后大顶堆中的k个数即为所求数。
11+
12+
大顶堆的特点:
13+
14+
父节点大于等于子节点(但是两个子节点之间的大小关系没有要求),这样可以做到沿着每条从根节点到叶子节点的路径,元素的键值都是以非升序排列的。
15+
堆是一个几乎完全的二叉树,所以具有和完全二叉树一样的特点,即一般是存储在一个数组A[n]中,A[i]的左子节点在A[2i]中,右子节点在A[2i+1]中(当他们存在的时候),A[i]的父亲节点在A[i/2]中(如果存在,i/2向下取整)。
16+
17+
18+
19+
### 两个辅助运算
20+
21+
#### SIFT-UP
22+
23+
##### 功能
24+
25+
当某个节点(H[i])的值大于他的父亲节点的值时,需要通过SITF-UP将这个节点 **沿着从H[i]到H[1]这条唯一的路径**
26+
上移到合适的位置以形成一个合格的堆。
27+
28+
##### 实现思路
29+
30+
将H[i]与其父亲节点H[i/2]比较,如果H[i]大于H[i/2],则将H[i]与H[i/2]互换,直到H[i]没有父节点或者H[i]不大于H[i/2]
31+
32+
##### 代码
33+
34+
```
35+
int SiftUp(int *H, int i) {
36+
37+
while (true) {
38+
if (i == 1) {
39+
break;//说明当前i是根节点
40+
}
41+
if (H[i] > H[(int) i / 2]) {//如果当前节点比父亲节点大
42+
int t;
43+
t = H[i];
44+
H[i] = H[(int) i / 2];
45+
H[(int) i / 2] = t;
46+
i = i / 2;
47+
} else {
48+
break;
49+
}
50+
}
51+
return 0;
52+
}
53+
```
54+
55+
56+
57+
#### SIFT-DOWN
58+
59+
##### 功能
60+
61+
当某个节点(H[i],i<=(int)n/2即 **非叶子节点**
62+
)的值小于它的两个子节点H[2i]和H[2i+1](如果存在的话)的最大值时,需要将SIFT-DOWN将渗到合适的位置。
63+
64+
##### 实现思路
65+
66+
将H[i]与其两个子节点中值最大的元素比较,如果小于最大的那个节点,则将H[i]与其最大的那个子节点互换。
67+
68+
##### 代码:
69+
70+
```
71+
int SiftDown(int *H, int i, int n) {
72+
while (true) {
73+
i = 2 * i;
74+
if (i > n) {
75+
break;
76+
}
77+
78+
if (i + 1 <= n) {
79+
if (H[i + 1] > H[i]) {//比较两个子节点哪个最大
80+
i++;
81+
}
82+
}
83+
84+
if (H[i] > H[(int) i / 2]) {
85+
int t;
86+
t = H[i];
87+
H[i] = H[(int) i / 2];
88+
H[(int) i / 2] = t;
89+
}
90+
}
91+
}
92+
```
93+
94+
### 创建堆(makeheap)
95+
96+
##### 功能
97+
98+
给出一个有n个元素的数组H[1….n],创建一个包含这些元素的堆。
99+
100+
##### 实现思路
101+
102+
类似于分治,首先,H的叶子节点(即最下面的一层单个元素)可以认为是若干个小堆,然后我们从倒数第二层开始,将倒数第二层和倒数第一层的元素进行适当调整,使得调整之后整个二叉完全数的最后两层是若干个子堆,按照这个思路,依次向上走,最终走到第1层的时候就可以保证整个完全二叉树是一个符合要求的堆。
103+
104+
需要注意的是对于一个完全二叉树, **倒数第二层的最后一个元素的下标为int(n/2)** ,(因为倒数第二层的最后一个节点的下标x应该满足x*2=n).
105+
106+
##### 算法时间复杂度分析
107+
108+
senta(n)
109+
110+
##### 代码
111+
112+
```
113+
void makeheap(int *H,int n){
114+
for (int i = n/2; i >=1 ; --i) {//从倒数第二层到第一层
115+
SiftDown(H,i,n);
116+
}
117+
}
118+
```
119+
120+
121+
[这里](../Code/28.py)

0 commit comments

Comments
 (0)