上药三品,神与气精

曾因酒醉鞭名马 生怕情多累美人


  • 首页

  • 关于

  • 分类

  • 标签

  • 归档

  • 搜索

字符串匹配-bm-kmp

发表于 2019-03-20 | 分类于 leetcode | 阅读次数:
字数统计: 575 | 阅读时长 ≈ 2

boyer-moore 算法

模式串的主串的匹配过程 看作模式串在主串不停地向后滑动

当遇到不匹配的字符时 bf rk都是模式串往后移动一位

那么有没有更高效的 往后移动多位呢

如果往后滑动的时候 有重合 无法匹配的时候 可以多滑动几位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

#!/usr/bin/python
# -*- coding: UTF-8 -*-

SIZE = 256


def bm(main, pattern):
"""
BM算法
匹配规则:
1. 坏字符规则
2. 好字符规则
:param main:
:param pattern:
:return:
"""
assert type(main) is str and type(pattern) is str
n, m = len(main), len(pattern)

if n <= m:
return 0 if main == pattern else -1

# bc
bc = [-1] * SIZE
generate_bc(pattern, m, bc)

# gs
suffix = [-1] * m
prefix = [False] * m
generate_gs(pattern, m, suffix, prefix)

i = 0
while i < n-m+1:
j = m - 1
while j >= 0:
if main[i+j] != pattern[j]:
break
else:
j -= 1

# pattern整个已被匹配,返回
if j == -1:
return i

# 1. bc规则计算后移位数
x = j - bc[ord(main[i+j])]

# 2. gs规则计算后移位数
y = 0
if j != m - 1: # 存在gs
y = move_by_gs(j, m, suffix, prefix)

i += max(x, y)

return -1


def generate_bc(pattern, m, bc):
"""
生成坏字符哈希表
:param pattern:
:param m:
:param bc:
:return:
"""
for i in range(m):
bc[ord(pattern[i])] = i


def generate_gs(pattern, m, suffix, prefix):
"""
好后缀预处理
:param pattern:
:param m:
:param suffix:
:param prefix:
:return:
"""
for i in range(m-1):
k = 0 # pattern[:i+1]和pattern的公共后缀长度
for j in range(i, -1, -1):
if pattern[j] == pattern[m-1-k]:
k += 1
suffix[k] = j
if j == 0:
prefix[k] = True
else:
break


def move_by_gs(j, m, suffix, prefix):
"""
通过好后缀计算移动值
需要处理三种情况:
1. 整个好后缀在pattern仍能找到
2. 好后缀里存在 *后缀子串* 能和pattern的 *前缀* 匹配
3. 其他
:param j:
:param m:
:param suffix:
:param prefix:
:return:
"""
k = m - 1 - j # j指向从后往前的第一个坏字符,k是此次匹配的好后缀的长度

if suffix[k] != -1: # 1. 整个好后缀在pattern剩余字符中仍有出现
return j - suffix[k] + 1
else:
for r in range(j+2, m): # 2. 后缀子串从长到短搜索
if prefix[m-r]:
return r
return m # 3. 其他情况


if __name__ == '__main__':
print('--- search ---')
m_str = 'dfasdeeeetewtweyyyhtruuueyytewtweyyhtrhrth'
p_str = 'eyytewtweyy'
print('[Built-in Functions] result:', m_str.find(p_str))
print('[bm] result:', bm(m_str, p_str))

字符串匹配-bf-rk

发表于 2019-03-19 | 分类于 leetcode | 阅读次数:
字数统计: 632 | 阅读时长 ≈ 3

主串 子串(模式串)

BF算法 在主串中检查起始位置分别是0、1、2…n-m且长度为m的n-m+1个子串

时间复杂度是n*m

但是在实际开发的过程中 是比较常用的

因为

大部分情况下 模式串和主串的长度都不会太长

而且每次模式串与主串中的子串匹配的时候 当中途遇到不能匹配的字符时 就停止了 不需要把字符串都比对一下 大部分情况下 够用

朴素字符串匹配算法思想简单 代码实现也非常简单 简单意味着不容易出错
在满足性能要求的前提下 简单是首选

RK

在朴素字符串匹配的基础上 引入哈希

对每个子串分别求哈希值 然后拿子串的哈希值与模式串的哈希值比较

理想情况下的时间复杂度是n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from time import time


def bf(main, pattern):
"""
字符串匹配,bf暴搜
:param main: 主串
:param pattern: 模式串
:return:
"""

n = len(main)
m = len(pattern)

if n <= m:
return 0 if pattern == main else -1

for i in range(n-m+1):
for j in range(m):
if main[i+j] == pattern[j]:
if j == m-1:
return i
else:
continue
else:
break
return -1


def simple_hash(s, start, end):
"""
计算子串的哈希值
每个字符取acs-ii码后求和
:param s:
:param start:
:param end:
:return:
"""

assert start <= end

ret = 0
for c in s[start: end+1]:
ret += ord(c)
return ret


def rk(main, pattern):
n = len(main)
m = len(pattern)

if n <= m:
return 0 if pattern == main else -1

# 子串哈希值表
hash_memo = [None] * (n-m+1)
hash_memo[0] = simple_hash(main, 0, m-1)
for i in range(1, n-m+1):
hash_memo[i] = hash_memo[i-1] - simple_hash(main, i-1, i-1) + simple_hash(main, i+m-1, i+m-1)

# 模式串哈希值
hash_p = simple_hash(pattern, 0, m-1)

for i, h in enumerate(hash_memo):
# 可能存在哈希冲突
if h == hash_p:
if pattern == main[i:i+m]:
return i
else:
continue
return -1


if __name__ == '__main__':
m_str = 'a'*10000
p_str = 'a'*200+'b'

print('--- time consume ---')
t = time()
print('[bf] result:', bf(m_str, p_str))
print('[bf] time cost: {0:.5}s'.format(time()-t))

t = time()
print('[rk] result:', rk(m_str, p_str))
print('[rk] time cost: {0:.5}s'.format(time()-t))

print('')
print('--- search ---')
m_str = 'thequickbrownfoxjumpsoverthelazydog'
p_str = 'jump'
print('[bf] result:', bf(m_str, p_str))
print('[rk] result:', rk(m_str, p_str))

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
--- time consume ---
('[bf] result:', -1)
[bf] time cost: 0.27776s
('[rk] result:', -1)
[rk] time cost: 0.012524s

--- search ---
('[bf] result:', 16)
('[rk] result:', 16)

# 如上是普通cpython 2的输出

# 纯粹的py代码 可以使用pypy来加速

--- time consume ---
('[bf] result:', -1)
[bf] time cost: 0.033931s
('[rk] result:', -1)
[rk] time cost: 0.02212s

--- search ---
('[bf] result:', 16)
('[rk] result:', 16)

leetcode-bigintmulti

发表于 2019-03-19 | 分类于 leetcode | 阅读次数:
字数统计: 958 | 阅读时长 ≈ 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

def karatsuba(x, y):
"""Function to multiply 2 numbers in a more efficient manner than the grade school algorithm"""
if len(str(x)) == 1 or len(str(y)) == 1:
return x * y
else:
n = max(len(str(x)), len(str(y)))
nby2 = n / 2

a = x / 10**(nby2)
b = x % 10**(nby2)
c = y / 10**(nby2)
d = y % 10**(nby2)

ac = karatsuba(a, c)
bd = karatsuba(b, d)
ad_plus_bc = karatsuba(a + b, c + d) - ac - bd

# this little trick, writing n as 2*nby2 takes care of both even and
# odd n
prod = ac * 10**(2 * nby2) + (ad_plus_bc * 10**nby2) + bd

return prod


if __name__ == "__main__":
print(karatsuba(86123457, 12345678))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

#! /usr/local/bin/python3.6
"""
Multiplication of big-digit values with Toom-Cook 3-way method
"""
import random
import sys
import traceback


class MultiplyToomCook3:
D_MAX = 729 # Maximum number of digits (power of 3)
D = 729 # Digits of computation (<= D_MAX)

def __init__(self):
self.a = [random.randrange(10) for _ in range(self.D)]
self.b = [random.randrange(10) for _ in range(self.D)]

def compute(self):
""" Computation of multiplication """
try:
for i in range(self.D_MAX - len(self.a)):
self.a.append(0)
for i in range(self.D_MAX - len(self.b)):
self.b.append(0)
z = self.__multiply_toom_cook_3(self.a, self.b)
z = self.__do_carry(z)
self.__display(self.a, self.b, z)
except Exception as e:
raise

def __multiply_normal(self, a, b):
""" Normal multiplication
:param list a
:param list b
:return list z
"""
try:
a_len, b_len = len(a), len(b)
z = [0 for _ in range(a_len + b_len)]
for j in range(b_len):
for i in range(a_len):
z[j + i] += a[i] * b[j]
return z
except Exception as e:
raise

def __multiply_toom_cook_3(self, a, b):
""" Toom-Cook 3-way multiplication
:param list a
:param list b
:return list z
"""
a_m1, a_m2, a_0, a_1, a_inf = [], [], [], [], []
b_m1, b_m2, b_0, b_1, b_inf = [], [], [], [], []
c_m1, c_m2, c_0, c_1, c_inf = [], [], [], [], []
c0, c1, c2, c3, c4 = [], [], [], [], []
try:
t_len = len(a)
# 9桁(配列9個)になった場合は標準乗算
if t_len <= 9:
return self.__multiply_normal(a, b)
a0 = a[:(t_len // 3)]
a1 = a[(t_len // 3):(t_len * 2 // 3)]
a2 = a[(t_len * 2 // 3):]
b0 = b[:(t_len // 3)]
b1 = b[(t_len // 3):(t_len * 2 // 3)]
b2 = b[(t_len * 2 // 3):]
for i in range(t_len // 3):
a_m2.append((a2[i] << 2) - (a1[i] << 1) + a0[i])
b_m2.append((b2[i] << 2) - (b1[i] << 1) + b0[i])
for i in range(t_len // 3):
a_m1.append(a2[i] - a1[i] + a0[i])
b_m1.append(b2[i] - b1[i] + b0[i])
a_0, b_0 = a0, b0
for i in range(t_len // 3):
a_1.append(a2[i] + a1[i] + a0[i])
b_1.append(b2[i] + b1[i] + b0[i])
a_inf, b_inf= a2, b2
c_m2 = self.__multiply_toom_cook_3(a_m2, b_m2)
c_m1 = self.__multiply_toom_cook_3(a_m1, b_m1)
c_0 = self.__multiply_toom_cook_3(a_0, b_0)
c_1 = self.__multiply_toom_cook_3(a_1, b_1)
c_inf = self.__multiply_toom_cook_3(a_inf, b_inf)
c4 = c_inf
for i in range((t_len // 3) * 2):
c = -c_m2[i]
c += (c_m1[i] << 1) + c_m1[i]
c -= (c_0[i] << 1) + c_0[i]
c += c_1[i]
c += (c_inf[i] << 3) + (c_inf[i] << 2)
c = c // 6
c3.append(c)
for i in range((t_len // 3) * 2):
c = (c_m1[i] << 1) + c_m1[i]
c -= (c_0[i] << 2) + (c_0[i] << 1)
c += (c_1[i] << 1) + c_1[i]
c -= (c_inf[i] << 2) + (c_inf[i] << 1)
c = c // 6
c2.append(c)
for i in range((t_len // 3) * 2):
c = c_m2[i]
c -= (c_m1[i] << 2) + (c_m1[i] << 1)
c += (c_0[i] << 1) + c_0[i]
c += (c_1[i] << 1)
c -= (c_inf[i] << 3) + (c_inf[i] << 2)
c = c // 6
c1.append(c)
c0 = c_0
z = c0 + c2 + c4
for i in range((t_len // 3) * 2):
z[i + t_len // 3] += c1[i]
for i in range((t_len // 3) * 2):
z[i + t_len] += c3[i]
return z
except Exception as e:
raise

def __do_carry(self, a):
""" Process of carrying
:param list a
:return list a
"""
cr = 0

try:
for i in range(len(a)):
a[i] += cr
cr = a[i] // 10
a[i] -= cr * 10
if cr != 0:
print("[ OVERFLOW!! ] ", cr)
return a
except Exception as e:
raise

def __display(self, a, b, z):
""" Display
:param list a
:param list b
:param list z
"""
a_len = self.D_MAX
b_len = self.D_MAX
z_len = self.D_MAX * 2
try:
while a[a_len - 1] == 0:
if a[a_len - 1] == 0:
a_len -= 1
while b[b_len - 1] == 0:
if b[b_len - 1] == 0:
b_len -= 1
while z[z_len - 1] == 0:
if z[z_len - 1] == 0:
z_len -= 1
print("a =")
for i in reversed(range(a_len)):
print(a[i], end="")
if (a_len - i) % 10 == 0:
print(" ", end="")
if (a_len - i) % 50 == 0:
print()
print()
print("b =")
for i in reversed(range(b_len)):
print(b[i], end="")
if (b_len - i) % 10 == 0:
print(" ", end="")
if (b_len - i) % 50 == 0:
print()
print()
print("z =")
for i in reversed(range(z_len)):
print(z[i], end="")
if (z_len - i) % 10 == 0:
print(" ", end="")
if (z_len - i) % 50 == 0:
print()
print()
except Exception as e:
raise


if __name__ == '__main__':
try:
obj = MultiplyToomCook3()
obj.compute()
except Exception as e:
traceback.print_exc()
sys.exit(1)

leetcode-linklist

发表于 2019-03-19 | 分类于 leetcode | 阅读次数:
字数统计: 1.3k | 阅读时长 ≈ 6

输出单链表倒数第k个节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 双指针法

ListNode* findKthTail(ListNode *pHead, int K){
if (NULL == pHead || K == 0)
return NULL;
//p1,p2均指向头节点
ListNode *p1 = pHead;
ListNode *p2 = pHead;
//p1先出发,前进K个节点
for (int i = 0; i < K; i++) {
if (p1)//防止k大于链表节点的个数
p1 = p1->_next;
else
return NULL;
}

while (p1)//如果p1没有到达链表结尾,则p1,p2继续遍历
{
p1 = p1->_next;
p2 = p2->_next;
}
return p2;//当p1到达末尾时,p2正好指向倒数第K个节点
}

链表中存在环的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
bool isExistLoop(ListNode* pHead)  {  
ListNode* fast;//慢指针,每次前进一个节点
ListNode* slow;//快指针,每次前进2个节点
slow = fast = pHead ; //两个指针均指向链表头节点
//当没有到达链表结尾,则继续前进
while (slow != NULL && fast -> next != NULL) {
slow = slow -> next ; //慢指针前进一个节点
fast = fast -> next -> next ; //快指针前进两个节点
if (slow == fast) //若两个指针相遇,且均不为NULL则存在环
return true ;
}
//到达末尾仍然没有相遇,则不存在环
return false ;
}

// 快慢指针

//找到环中的相遇节点
ListNode* getMeetingNode(ListNode* pHead) // 假设为带头节点的单链表
{

ListNode* fast;//慢指针,每次前进一个节点
ListNode* slow;//快指针,每次前进2个节点
slow = fast = pHead ; //两个指针均指向链表头节点
//当没有到达链表结尾,则继续前进
while (slow != NULL && fast -> next != NULL){
slow = slow -> next ; //慢指针前进一个节点
fast = fast -> next -> next ; //快指针前进两个节点
if (slow == fast) //若两个指针相遇,且均不为NULL则存在环
return slow;
}

//到达末尾仍然没有相遇,则不存在环
return NULL ;
}
//找出环的入口节点
ListNode* getEntryNodeOfLoop(ListNode* pHead){
ListNode* meetingNode = getMeetingNode(pHead); // 先找出环中的相遇节点
if (meetingNode == NULL)
return NULL;
ListNode* p1 = meetingNode;
ListNode* p2 = pHead;
while (p1 != p2) // p1和p2以相同的速度向前移动,当p2指向环的入口节点时,p1已经围绕着环走了n圈又回到了入口节点。
{
p1 = p1->next;
p2 = p2->next;
}
//返回入口节点
return p1;
}

// 计算环的长度

int getLoopLength(ListNode* head){
ListNode* slow = head;
ListNode* fast = head;
while ( fast && fast->next ){
slow = slow->next;
fast = fast->next->next;
if ( slow == fast )//第一次相遇
break;
}
//slow与fast继续前进
slow = slow->next;
fast = fast->next->next;
int length = 1; //环长度
while ( fast != slow )//再次相遇
{
slow = slow->next;
fast = fast->next->next;
length ++; //累加
}
//当slow与fast再次相遇,得到环长度
return length;
}

使用链表实现大数相加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

ListNode* numberAddAsList(ListNode* l1, ListNode* l2) {
ListNode *ret = l1, *pre = l1;
int up = 0;
while (l1 != NULL && l2 != NULL) {
//数值相加
l1->val = l1->val + l2->val + up;
//计算是否有进位
up = l1->val / 10;
//保留计算结果的个位
l1->val %= 10;
//记录当前节点位置
pre = l1;
//同时向后移位
l1 = l1->next;
l2 = l2->next;
}
//若l1到达末尾,说明l1长度小于l2
if (l1 == NULL)
//pre->next指向l2的当前位置
pre->next = l2;
//l1指针指向l2节点当前位置
l1 = pre->next;
//继续计算剩余节点
while (l1 != NULL) {
l1->val = l1->val + up;
up = l1->val / 10;
l1->val %= 10;
pre = l1;
l1 = l1->next;
}

//最高位计算有进位,则新建一个节点保留最高位
if (up != 0) {
ListNode *tmp = new ListNode(up);
pre->next = tmp;
}
//返回计算结果链表
return ret;
}

有序链表合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ListNode* mergeTwoOrderedLists(ListNode* pHead1, ListNode* pHead2){
ListNode* newHead = NULL;
if (NULL == pHead1){
return pHead2;
}else if(NULL ==pHead2){
return pHead2;
}else{
if (pHead1->data < pHead2->data){
newHead = pHead1;
newHead->next = mergeTwoOrderedLists(pHead1->next, pHead2);
}else{
newHead = pHead2;
newHead->next = mergeTwoOrderedLists(pHead1, pHead2->next);
}
return newHead;
}
}

删除链表中节点 要求时间复杂度为1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void deleteNode(ListNode **pHead, ListNode* pDelNode) {
if(pDelNode == NULL)
return;
if(pDelNode->next != NULL){
ListNode *pNext = pDelNode->next;
//下一个节点值赋给待删除节点
pDelNode->val = pNext->val;
//待删除节点指针指后面第二个节点
pDelNode->next = pNext->next;
//删除待删除节点的下一个节点
delete pNext;
pNext = NULL;
}else if(*pHead == pDelNode)//删除的节点是头节点
{
delete pDelNode;
pDelNode= NULL;
*pHead = NULL;
} else//删除的是尾节点
{
ListNode *pNode = *pHead;
while(pNode->next != pDelNode) {
pNode = pNode->next;
}
pNode->next = NULL;
delete pDelNode;
pDelNode= NULL;
}
}

从尾到头打印链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> value;
ListNode *p=NULL;
p=head;
stack<int> stk;
while(p!=NULL){
stk.push(p->val);
p=p->next;
}
while(!stk.empty()){
value.push_back(stk.top());
stk.pop();
}
return value;
}
};


class Solution {
public:
vector<int> value;
vector<int> printListFromTailToHead(ListNode* head) {
ListNode *p=NULL;
p=head;
if(p!=NULL){
if(p->next!=NULL){
printListFromTailToHead(p->next);
}
value.push_back(p->val);
}
return value;
}
};

反转链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

// 迭代

class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
ListNode* cur = head;
while(cur != NULL){
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
};


//递归

class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 递归终止条件
if(head == NULL || head->next == NULL)
return head;

ListNode* rhead = reverseList(head->next);
// head->next此刻指向head后面的链表的尾节点
// head->next->next = head把head节点放在了尾部
head->next->next = head;
head->next = NULL;
return rhead;
}
};

leetcode-queue

发表于 2019-03-19 | 分类于 leetcode | 阅读次数:
字数统计: 316 | 阅读时长 ≈ 1

有效的括号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
char[] chars = s.toCharArray();
for (char aChar : chars) {
if (stack.size() == 0) {
stack.push(aChar);
} else if (isSym(stack.peek(), aChar)) {
stack.pop();
} else {
stack.push(aChar);
}
}
return stack.size() == 0;
}

private boolean isSym(char c1, char c2) {
return (c1 == '(' && c2 == ')') || (c1 == '[' && c2 == ']') || (c1 == '{' && c2 == '}');
}
}

两个栈 实现队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Stack<Integer> in = new Stack<Integer>();
Stack<Integer> out = new Stack<Integer>();

public void push(int node) {
in.push(node);
}

public int pop() throws Exception {
if (out.isEmpty())
while (!in.isEmpty())
out.push(in.pop());

if (out.isEmpty())
throw new Exception("queue is empty");

return out.pop();
}

栈的压入 弹出序列

1
2
3
4
5
6
7
8
9
10
11
12
13
public boolean IsPopOrder(int[] pushSequence, int[] popSequence) {
int n = pushSequence.length;
Stack<Integer> stack = new Stack<>();
for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) {
stack.push(pushSequence[pushIndex]);
while (popIndex < n && !stack.isEmpty()
&& stack.peek() == popSequence[popIndex]) {
stack.pop();
popIndex++;
}
}
return stack.isEmpty();
}

包含min 函数的栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private Stack<Integer> dataStack = new Stack<>();
private Stack<Integer> minStack = new Stack<>();

public void push(int node) {
dataStack.push(node);
minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node));
}

public void pop() {
dataStack.pop();
minStack.pop();
}

public int top() {
return dataStack.peek();
}

public int min() {
return minStack.peek();
}

计算器

1
2


其他题

1
2


1…272829…109
John Cheung

John Cheung

improve your python skills

543 日志
33 分类
45 标签
RSS
GitHub Email
© 2020 John Cheung
本站访客数:
|
主题 — NexT.Pisces v5.1.4
博客全站共226.3k字