mirror of
https://github.com/heqin-zhu/algorithm.git
synced 2024-03-22 13:30:46 +08:00
Add binaryheap, circularqueue, linkedlist, maxxor, union find set
This commit is contained in:
parent
273702e4e4
commit
b6805c66ce
43
README.md
43
README.md
|
@ -2,16 +2,12 @@
|
|||
# Algorithm
|
||||
>Notes and codes for learning algorithm and data structures :smiley:
|
||||
|
||||
Some pictures and ideas are from `<<Introduction to Algotithm>>
|
||||
Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
||||
|
||||
I use python 3.6+ and c++ to implements them.
|
||||
Since I used f-Strings in python, you may use python 3.6+ to run the following python scripts.
|
||||
|
||||
>>I am still learning new things and this repo is always updating.
|
||||
I use python 3.6+ and c/c++ to implement them.
|
||||
|
||||
# Notice
|
||||
Currently, Github can't render latex math formulas.
|
||||
So,if you wannt to view the notes which contain latex math formulas and are in markdown format, you can visit [my blog](https://mbinary.coding.me)
|
||||
Currently, Github can't render latex math formulas.Thus,if you want to view the markodwn notes which contain latex math formulas, you can visit [my blog](https://mbinary.coding.me)
|
||||
|
||||
# Index
|
||||
* [.](.)
|
||||
|
@ -21,12 +17,15 @@ So,if you wannt to view the notes which contain latex math formulas and are in m
|
|||
* [allOone](./dataStructure/allOone)
|
||||
* [bTree.py](./dataStructure/bTree.py)
|
||||
* [binaryHeap.py](./dataStructure/binaryHeap.py)
|
||||
* [binaryHeap1.py](./dataStructure/binaryHeap1.py)
|
||||
* [binaryTree.py](./dataStructure/binaryTree.py)
|
||||
* [circularQueue.py](./dataStructure/circularQueue.py)
|
||||
* [graph](./dataStructure/graph)
|
||||
* [hashTable.py](./dataStructure/hashTable.py)
|
||||
* [huffman](./dataStructure/huffman)
|
||||
* [intervalTree.py](./dataStructure/intervalTree.py)
|
||||
* [leftHeap.py](./dataStructure/leftHeap.py)
|
||||
* [linkedList.py](./dataStructure/linkedList.py)
|
||||
* [loserTree.py](./dataStructure/loserTree.py)
|
||||
* [map.cc](./dataStructure/map.cc)
|
||||
* [polynomial.cpp](./dataStructure/polynomial.cpp)
|
||||
|
@ -35,6 +34,7 @@ So,if you wannt to view the notes which contain latex math formulas and are in m
|
|||
* [redBlackTree0.py](./dataStructure/redBlackTree0.py)
|
||||
* [splayTree.py](./dataStructure/splayTree.py)
|
||||
* [trie](./dataStructure/trie)
|
||||
* [unionFindSet](./dataStructure/unionFindSet)
|
||||
* [winnerTree.py](./dataStructure/winnerTree.py)
|
||||
* [divideAndConquer](./divideAndConquer)
|
||||
* [min_distance_of_n_points.py](./divideAndConquer/min_distance_of_n_points.py)
|
||||
|
@ -59,29 +59,15 @@ So,if you wannt to view the notes which contain latex math formulas and are in m
|
|||
* [stoneGame.py](./dynamicProgramming/stoneGame.py)
|
||||
* [testVec2d.hs](./dynamicProgramming/testVec2d.hs)
|
||||
* [wildcard_matching.py](./dynamicProgramming/wildcard_matching.py)
|
||||
* [graph](./graph)
|
||||
* [isBipartGraph.py](./graph/isBipartGraph.py)
|
||||
* [math](./math)
|
||||
* [README.md](./math/README.md)
|
||||
* [euler.py](./math/euler.py)
|
||||
* [factor.py](./math/factor.py)
|
||||
* [gcd.py](./math/gcd.py)
|
||||
* [isPrime.py](./math/isPrime.py)
|
||||
* [modulo_equation.py](./math/modulo_equation.py)
|
||||
* [num_weight.py](./math/num_weight.py)
|
||||
* [permute_back_track.py](./math/permute_back_track.py)
|
||||
* [permute_cantor.c](./math/permute_cantor.c)
|
||||
* [permute_divide_and_conquer.py](./math/permute_divide_and_conquer.py)
|
||||
* [permute_next_arrangement.c](./math/permute_next_arrangement.c)
|
||||
* [primesLEn.hs](./math/primesLEn.hs)
|
||||
* [numericalAnalysis](./numericalAnalysis)
|
||||
* [README.md](./numericalAnalysis/README.md)
|
||||
* [interplotion.py](./numericalAnalysis/interplotion.py)
|
||||
* [iteration.py](./numericalAnalysis/iteration.py)
|
||||
* [least_square.py](./numericalAnalysis/least_square.py)
|
||||
* [linear_equation.py](./numericalAnalysis/linear_equation.py)
|
||||
* [numerical_differential.py](./numericalAnalysis/numerical_differential.py)
|
||||
* [numerical_integration.py](./numericalAnalysis/numerical_integration.py)
|
||||
* [solve-linear-by-iteration.py](./numericalAnalysis/solve-linear-by-iteration.py)
|
||||
* [vector_norm.py](./numericalAnalysis/vector_norm.py)
|
||||
* [convertWeight.py](./math/convertWeight.py)
|
||||
* [fastPow.py](./math/fastPow.py)
|
||||
* [numberTheory](./math/numberTheory)
|
||||
* [numericalAnalysis](./math/numericalAnalysis)
|
||||
* [permute](./math/permute)
|
||||
* [search](./search)
|
||||
* [8Astar.py](./search/8Astar.py)
|
||||
* [BFS_knight.hs](./search/BFS_knight.hs)
|
||||
|
@ -91,6 +77,7 @@ So,if you wannt to view the notes which contain latex math formulas and are in m
|
|||
* [sort](./sort)
|
||||
* [binaryTree.py](./sort/binaryTree.py)
|
||||
* [heapSort.py](./sort/heapSort.py)
|
||||
* [quickSort.c](./sort/quickSort.c)
|
||||
* [quickSort.py](./sort/quickSort.py)
|
||||
* [radixSort.py](./sort/radixSort.py)
|
||||
* [select.py](./sort/select.py)
|
||||
|
|
72
dataStructure/binaryHeap1.py
Normal file
72
dataStructure/binaryHeap1.py
Normal file
|
@ -0,0 +1,72 @@
|
|||
from functools import partial
|
||||
class heap:
|
||||
def __init__(self,lst,reverse = False):
|
||||
self.data= heapify(lst,reverse)
|
||||
self.cmp = partial(lambda i,j,r:cmp(self.data[i],self.data[j],r),r= reverse)
|
||||
def getTop(self):
|
||||
return self.data[0]
|
||||
def __getitem__(self,idx):
|
||||
return self.data[idx]
|
||||
def __bool__(self):
|
||||
return self.data != []
|
||||
def popTop(self):
|
||||
ret = self.data[0]
|
||||
n = len(self.data)
|
||||
cur = 1
|
||||
while cur * 2<=n:
|
||||
chd = cur-1
|
||||
r_idx = cur*2
|
||||
l_idx = r_idx-1
|
||||
if r_idx==n:
|
||||
self.data[chd] = self.data[l_idx]
|
||||
break
|
||||
j = l_idx if self.cmp(l_idx,r_idx)<0 else r_idx
|
||||
self.data[chd] = self.data[j]
|
||||
cur = j+1
|
||||
self.data[cur-1] = self.data[-1]
|
||||
self.data.pop()
|
||||
return ret
|
||||
|
||||
def addNode(self,val):
|
||||
self.data.append(val)
|
||||
self.data = one_heapify(len(self.data)-1)
|
||||
|
||||
|
||||
def cmp(n1,n2,reverse=False):
|
||||
fac = -1 if reverse else 1
|
||||
if n1 < n2: return -fac
|
||||
elif n1 > n2: return fac
|
||||
return 0
|
||||
|
||||
def heapify(lst,reverse = False):
|
||||
for i in range(len(lst)):
|
||||
lst = one_heapify(lst,i,reverse)
|
||||
return lst
|
||||
def one_heapify(lst,cur,reverse = False):
|
||||
cur +=1
|
||||
while cur>1:
|
||||
chd = cur-1
|
||||
prt = cur//2-1
|
||||
if cmp(lst[prt],lst[chd],reverse)<0:
|
||||
break
|
||||
lst[prt],lst[chd] = lst[chd], lst[prt]
|
||||
cur = prt+1
|
||||
return lst
|
||||
def heapSort(lst,reverse = False):
|
||||
lst = lst.copy()
|
||||
hp = heap(lst,reverse)
|
||||
ret = []
|
||||
while hp:
|
||||
ret.append(hp.popTop())
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from random import randint
|
||||
n = randint(10,20)
|
||||
lst = [randint(0,100) for i in range(n)]
|
||||
print('random : ', lst)
|
||||
print('small-heap: ', heapify(lst))
|
||||
print('big-heap : ', heapify(lst,True))
|
||||
print('ascend : ', heapSort(lst))
|
||||
print('descend : ', heapSort(lst,True))
|
76
dataStructure/circularQueue.py
Normal file
76
dataStructure/circularQueue.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
class MyCircularQueue:
|
||||
|
||||
def __init__(self, k):
|
||||
"""
|
||||
Initialize your data structure here. Set the size of the queue to be k.
|
||||
:type k: int
|
||||
"""
|
||||
self.size = k+1
|
||||
self.data = [0]*self.size
|
||||
self.head = self.rear = 0
|
||||
|
||||
def enQueue(self, value):
|
||||
"""
|
||||
Insert an element into the circular queue. Return true if the operation is successful.
|
||||
:type value: int
|
||||
:rtype: bool
|
||||
"""
|
||||
if self.isFull():
|
||||
return False
|
||||
self.data[self.rear] = value
|
||||
self.rear = (self.rear+1)%self.size
|
||||
return True
|
||||
def deQueue(self):
|
||||
"""
|
||||
Delete an element from the circular queue. Return true if the operation is successful.
|
||||
:rtype: bool
|
||||
"""
|
||||
if self.isEmpty():
|
||||
return False
|
||||
self.head = (self.head+1)%self.size
|
||||
return True
|
||||
|
||||
def Front(self):
|
||||
"""
|
||||
Get the front item from the queue.
|
||||
:rtype: int
|
||||
"""
|
||||
if self.isEmpty():
|
||||
return -1
|
||||
return self.data[self.head]
|
||||
|
||||
|
||||
def Rear(self):
|
||||
"""
|
||||
Get the last item from the queue.
|
||||
:rtype: int
|
||||
"""
|
||||
if self.isEmpty():
|
||||
return -1
|
||||
return self.data[(self.rear-1)%self.size]
|
||||
|
||||
def isEmpty(self):
|
||||
"""
|
||||
Checks whether the circular queue is empty or not.
|
||||
:rtype: bool
|
||||
"""
|
||||
return self.head ==self.rear
|
||||
|
||||
|
||||
def isFull(self):
|
||||
"""
|
||||
Checks whether the circular queue is full or not.
|
||||
:rtype: bool
|
||||
"""
|
||||
return (self.head - self.rear)%self.size ==1
|
||||
|
||||
|
||||
|
||||
# Your MyCircularQueue object will be instantiated and called as such:
|
||||
# obj = MyCircularQueue(k)
|
||||
# param_1 = obj.enQueue(value)
|
||||
# param_2 = obj.deQueue()
|
||||
# param_3 = obj.Front()
|
||||
# param_4 = obj.Rear()
|
||||
# param_5 = obj.isEmpty()
|
||||
# param_6 = obj.isFull()
|
84
dataStructure/linkedList.py
Normal file
84
dataStructure/linkedList.py
Normal file
|
@ -0,0 +1,84 @@
|
|||
class node:
|
||||
def __init__(self,val,follow=None):
|
||||
self.val = val
|
||||
self.follow = follow
|
||||
class MyLinkedList:
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize your data structure here.
|
||||
"""
|
||||
|
||||
self.tail = self.head = node(None)
|
||||
|
||||
def get(self, index):
|
||||
"""
|
||||
Get the value of the index-th node in the linked list. If the index is invalid, return -1.
|
||||
:type index: int
|
||||
:rtype: int
|
||||
"""
|
||||
nd = self.head
|
||||
for i in range(index+1):
|
||||
nd = nd.follow
|
||||
if nd is None:return -1
|
||||
return nd.val
|
||||
|
||||
def addAtHead(self, val):
|
||||
"""
|
||||
Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
|
||||
:type val: int
|
||||
:rtype: void
|
||||
"""
|
||||
nd = node(val,self.head.follow)
|
||||
self.head .follow = nd
|
||||
if self.tail.val is None:self.tail = nd
|
||||
def addAtTail(self, val):
|
||||
"""
|
||||
Append a node of value val to the last element of the linked list.
|
||||
:type val: int
|
||||
:rtype: void
|
||||
"""
|
||||
self.tail.follow = node(val)
|
||||
self.tail = self.tail.follow
|
||||
|
||||
|
||||
def addAtIndex(self, index, val):
|
||||
"""
|
||||
Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
|
||||
:type index: int
|
||||
:type val: int
|
||||
:rtype: void
|
||||
"""
|
||||
nd = self.head
|
||||
for i in range(index):
|
||||
nd = nd.follow
|
||||
if nd is None:
|
||||
return
|
||||
new = node(val,nd.follow)
|
||||
nd.follow = new
|
||||
if self.tail == nd:
|
||||
self.tail = new
|
||||
|
||||
|
||||
def deleteAtIndex(self, index):
|
||||
"""
|
||||
Delete the index-th node in the linked list, if the index is valid.
|
||||
:type index: int
|
||||
:rtype: void
|
||||
"""
|
||||
nd = self.head
|
||||
for i in range(index):
|
||||
nd = nd.follow
|
||||
if nd is None:return
|
||||
if self.tail == nd.follow:self.tail = nd
|
||||
if nd.follow:nd.follow = nd.follow.follow
|
||||
|
||||
|
||||
|
||||
# Your MyLinkedList object will be instantiated and called as such:
|
||||
# obj = MyLinkedList()
|
||||
# param_1 = obj.get(index)
|
||||
# obj.addAtHead(val)
|
||||
# obj.addAtTail(val)
|
||||
# obj.addAtIndex(index,val)
|
||||
# obj.deleteAtIndex(index)
|
|
@ -61,7 +61,6 @@ class MapSum:
|
|||
nd[i] = node(i)
|
||||
nd = nd[i]
|
||||
nd.n = val
|
||||
|
||||
def visit(self,nd):
|
||||
ret = nd.n
|
||||
for chd in nd:
|
||||
|
|
70
dataStructure/trie/maxXor.py
Normal file
70
dataStructure/trie/maxXor.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : maxXor.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-22 09:51
|
||||
# Description:
|
||||
maximum_xor_of_two_numbers_in_an_array:
|
||||
using trie data structure
|
||||
O(k*n) where n=length(array),k is the max length of radix of num
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
class node:
|
||||
def __init__(self,key,hasKey = False):
|
||||
self.key = key
|
||||
self.hasKey = hasKey
|
||||
self.children={}
|
||||
def __getitem__(self,key):
|
||||
return self.children[key]
|
||||
def __len__(self):
|
||||
return len(self.children)
|
||||
def __setitem__(self,key,val):
|
||||
self.children[key]=val
|
||||
def __contains__(self,key):
|
||||
return key in self.children
|
||||
class trie:
|
||||
def __init__(self,maxDepth=32):
|
||||
self.root=node(None)
|
||||
self.maxDepth = maxDepth
|
||||
def add(self,num):
|
||||
nd = self.root
|
||||
s = bin(num)[2:].rjust(self.maxDepth,'0')
|
||||
for n in s:
|
||||
if n not in nd:
|
||||
nd[n]=node(n)
|
||||
nd=nd[n]
|
||||
def search(self,num):
|
||||
ret = 0
|
||||
nd = self.root
|
||||
s = bin(num)[2:].rjust(self.maxDepth,'0')
|
||||
for n in s:
|
||||
# note that it's the flip bit
|
||||
flip = '1' if n=='0' else '0'
|
||||
if flip in nd:
|
||||
ret=ret*2+1
|
||||
nd=nd[flip]
|
||||
else:
|
||||
ret*=2
|
||||
nd=nd[n]
|
||||
return ret
|
||||
|
||||
def findMaximumXOR(self, nums):
|
||||
"""
|
||||
:type nums: List[int]
|
||||
:rtype: int
|
||||
"""
|
||||
if not nums:return 0
|
||||
n = len(bin(max(nums)))-1
|
||||
t = trie(n)
|
||||
for i in nums:t.add(i)
|
||||
return max(t.search(i) for i in nums)
|
||||
|
||||
if __name__=='__main__':
|
||||
from random import randint
|
||||
nums = [randint(1,int(1e18)) for i in 100]
|
||||
findMaximumXOR(nums)
|
99
dataStructure/unionFindSet/accountsMerge.py
Normal file
99
dataStructure/unionFindSet/accountsMerge.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : accountsMerge.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-18 17:07
|
||||
# Description:
|
||||
给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址。
|
||||
|
||||
现在,我们想合并这些帐户。如果两个帐户都有一些共同的邮件地址,则两个帐户必定属于同一个人。请注意,即使两个帐户具有相同的名称,它们也可能属于不同的人,因为人们可能具有相同的名称。一个人最初可以拥有任意数量的帐户,但其所有帐户都具有相同的名称。
|
||||
|
||||
合并帐户后,按以下格式返回帐户:每个帐户的第一个元素是名称,其余元素是按顺序排列的邮箱地址。accounts 本身可以以任意顺序返回。
|
||||
|
||||
例子 1:
|
||||
|
||||
Input:
|
||||
accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]]
|
||||
Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]]
|
||||
Explanation:
|
||||
第一个和第三个 John 是同一个人,因为他们有共同的电子邮件 "johnsmith@mail.com"。
|
||||
第二个 John 和 Mary 是不同的人,因为他们的电子邮件地址没有被其他帐户使用。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
class Solution(object):
|
||||
def accountsMerge(self, accounts):
|
||||
"""
|
||||
:type accounts: List[List[str]]
|
||||
:rtype: List[List[str]]
|
||||
"""
|
||||
mailDic = {}
|
||||
for ct,i in enumerate(accounts):
|
||||
for j in i[1:]:
|
||||
mailDic[j] = (ct,i[0])
|
||||
mails = {mail:idx for idx,mail in enumerate(mailDic.keys())}
|
||||
mailNum = len(mails)
|
||||
self.findSet = [i for i in range(mailNum)]
|
||||
for li in accounts:
|
||||
n = len(li)
|
||||
for i in range(1,n-1):
|
||||
for j in range(i+1,n):
|
||||
self.union(mails[li[i]],mails[li[j]])
|
||||
dic = {}
|
||||
mails = {j:i for i,j in mails.items()}
|
||||
for i in range(mailNum):
|
||||
mail = mails[i]
|
||||
n = mailDic[mails[self.find(i)]][0]
|
||||
if n in dic:
|
||||
dic[n].append(mail)
|
||||
else:
|
||||
dic[n] = [mail]
|
||||
nameId = {i[0]:i[1] for i in mailDic.values()}
|
||||
return [[nameId[i]]+sorted(mail) for i,mail in dic.items()]
|
||||
def find(self,i):
|
||||
if self.findSet[i]!=i:
|
||||
n = self.find(self.findSet[i])
|
||||
self.findSet[i] = n
|
||||
return self.findSet[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.findSet[n] = self.findSet[j]
|
||||
|
||||
class Solution2:
|
||||
'''并查映射'''
|
||||
def accountsMerge(self, accounts):
|
||||
"""
|
||||
:type accounts: List[List[str]]
|
||||
:rtype: List[List[str]]
|
||||
"""
|
||||
mailDic = {j:ct for ct,i in enumerate(accounts) for j in i[1:]}
|
||||
self.findSet = {i:i for i in mailDic}
|
||||
for li in accounts:
|
||||
n = len(li)
|
||||
for i in range(1,n-1):
|
||||
for j in range(i+1,n):
|
||||
self.union(li[i],li[j])
|
||||
dic = {}
|
||||
for mail in self.findSet:
|
||||
n = mailDic[self.find(mail)]
|
||||
if n in dic:
|
||||
dic[n].append(mail)
|
||||
else:
|
||||
dic[n] = [mail]
|
||||
return [[accounts[i][0]]+sorted(mail) for i,mail in dic.items()]
|
||||
def find(self,i):
|
||||
if self.findSet[i]!=i:
|
||||
n = self.find(self.findSet[i])
|
||||
self.findSet[i] = n
|
||||
return self.findSet[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.findSet[n] = self.findSet[j]
|
42
dataStructure/unionFindSet/friendsCircle.py
Normal file
42
dataStructure/unionFindSet/friendsCircle.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : unionFind.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-18 14:53
|
||||
# Description:
|
||||
班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。
|
||||
|
||||
给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。如果 M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。你必须输出所有学生中的已知的朋友圈总数。
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
class Solution(object):
|
||||
def findCircleNum(self, M):
|
||||
"""
|
||||
:type M: List[List[int]]
|
||||
:rtype: int
|
||||
"""
|
||||
n = len(M)
|
||||
self.data = [i for i in range(n)]
|
||||
for i in range(n):
|
||||
for j in range(n):
|
||||
if M[i][j]==1:
|
||||
self.union(i,j)
|
||||
ret = set()
|
||||
for i in range(n):
|
||||
ret.add(self.find(i))
|
||||
return len(ret)
|
||||
def find(self,i):
|
||||
if self.data[i]!=i:
|
||||
self.data[i] = self.find(self.data[i])
|
||||
return self.data[i]
|
||||
def union(self,i,j):
|
||||
if i!=j:
|
||||
n = self.find(i)
|
||||
if n!=self.find(j):
|
||||
self.data[n]= self.data[j]
|
30
graph/isBipartGraph.py
Normal file
30
graph/isBipartGraph.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : isBipartGraph.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-21 15:00
|
||||
# Description: Judge if a graph is bipartite
|
||||
The theorical idea is to judge whether the graph has a odd-path circle. However, it's hard to implement.
|
||||
The following codes show a method that colors the nodes by dfs.
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
|
||||
def isBipartite(self, graph):
|
||||
"""
|
||||
:type graph: List[List[int]]
|
||||
:rtype: bool
|
||||
"""
|
||||
n = len(graph)
|
||||
self.node = graph
|
||||
self.color = {i:None for i in range(n)}
|
||||
return all(self.dfs(i,True) for i in range(n) if self.color[i] is None)
|
||||
def dfs(self,n,col=True):
|
||||
if self.color[n] is None:
|
||||
self.color[n]=col
|
||||
return all(self.dfs(i,not col) for i in self.node[n])
|
||||
else:return col==self.color[n]
|
31
math/fastPow.py
Normal file
31
math/fastPow.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : fastPow.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-17 21:39
|
||||
# Description: fast power
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
def fastPow(a,n):
|
||||
'''a^n'''
|
||||
rst = 1
|
||||
while n:
|
||||
if n%2:
|
||||
rst *=a
|
||||
n>>=1
|
||||
a*=a
|
||||
return rst
|
||||
|
||||
def fastMul(a,b):
|
||||
'''a*b'''
|
||||
rst = 0
|
||||
while b:
|
||||
if b&1:
|
||||
rst +=a
|
||||
b>>=1
|
||||
a*=2
|
|
@ -35,6 +35,16 @@ def factor(n):
|
|||
cycle_size *=2
|
||||
x_fixed = x
|
||||
return factor(fact)+factor(n//fact)
|
||||
def fact(n):
|
||||
f=2
|
||||
ret = []
|
||||
while f*f<=n:
|
||||
while not n%f:
|
||||
ret.append(f)
|
||||
n//f
|
||||
f+=1
|
||||
if n>1:ret.append(n)
|
||||
return ret
|
||||
|
||||
|
||||
if __name__=='__main__':
|
60
math/numberTheory/hammingDistance.py
Normal file
60
math/numberTheory/hammingDistance.py
Normal file
|
@ -0,0 +1,60 @@
|
|||
#coding: utf-8
|
||||
''' mbinary
|
||||
#######################################################################
|
||||
# File : hammingDistance.py
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-12-17 17:36
|
||||
# Description:
|
||||
hamming distance is the number of different position (or binary bit for number) of two strings.
|
||||
eg 'abac', 'ab': 2 1010,11 : 3
|
||||
#######################################################################
|
||||
'''
|
||||
|
||||
def hammingDistance(a,b):
|
||||
if isinstance(a,int):
|
||||
n = a^b
|
||||
ct = 0
|
||||
while n:
|
||||
ct+=n%2
|
||||
n>>=1
|
||||
return ct
|
||||
else:
|
||||
n,m = len(a),len(b)
|
||||
ret = 0
|
||||
for i,j in zip(a,b):
|
||||
ret+= i==j
|
||||
return ret+abs(n-m)
|
||||
|
||||
def totalHammingDistance(lst):
|
||||
'''return sum of any two items(num or lst( str)) in lst'''
|
||||
length = len(lst)
|
||||
if length ==0:return 0
|
||||
if isinstance(lst[0],int):
|
||||
bits = [0] * len(bin(max(lst)))
|
||||
for n in lst:
|
||||
ct = 0
|
||||
while n:
|
||||
if n%2==1:
|
||||
bits[ct]+=1
|
||||
ct+=1
|
||||
n>>=1
|
||||
return sum(i*(length-i) for i in bits)
|
||||
else:
|
||||
mx = len(max(lst,key=len))
|
||||
position = [dict() for i in range(mx)]
|
||||
for li in lst:
|
||||
for i,x in enumerate(li):
|
||||
if x in position[i]:
|
||||
position[i][x] +=1
|
||||
else:
|
||||
position[i][x] =1
|
||||
ret = 0
|
||||
for dic in position:
|
||||
left = length
|
||||
for i in dic.values():
|
||||
ret+=i*(left-i) # key step
|
||||
left -=i # key step
|
||||
return ret
|
|
@ -1,12 +1,13 @@
|
|||
/* mbinary
|
||||
#########################################################################
|
||||
# File : permute_next_arrangement.c
|
||||
# File : permute_next_permutation.c
|
||||
# Author: mbinary
|
||||
# Mail: zhuheqin1@gmail.com
|
||||
# Blog: https://mbinary.coding.me
|
||||
# Github: https://github.com/mbinary
|
||||
# Created Time: 2018-11-17 14:31
|
||||
# Description:
|
||||
# Description: support duplicate values.
|
||||
eg [1,1,5] nextPermutation [1,5,1]
|
||||
#########################################################################
|
||||
*/
|
||||
#include<stdio.h>
|
||||
|
@ -18,28 +19,27 @@ void swap(int*arr,int i,int j)
|
|||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
void nextArrangement(int *arr,int n)
|
||||
void reverse(int *arr,int i,int j)
|
||||
{
|
||||
if(arr[n-1]>arr[n-2]){
|
||||
swap(arr,n-1,n-2);
|
||||
}else{
|
||||
while (i<j)swap(arr,i++,j--);
|
||||
}
|
||||
void nextPermutation(int *arr,int n)
|
||||
{
|
||||
if(n>1){
|
||||
int i;
|
||||
for(i=n-1;i>0;--i){
|
||||
if(arr[i]>arr[i-1])break;
|
||||
}
|
||||
if(i==0){//reverse arrangement, n,n-1,...,1
|
||||
for(;i<n;++i)arr[i] = i;
|
||||
return ;
|
||||
}
|
||||
i=i-1;
|
||||
for(int j=n-1;j>i;j--){
|
||||
if(arr[j]>arr[i]){
|
||||
int tmp = arr[j];
|
||||
for(int k = j;k>i;--k)arr[k] = arr[k-1];
|
||||
arr[i] =tmp;
|
||||
break;
|
||||
i-=1;
|
||||
if(i>=0){
|
||||
for(int j=n-1;j>i;j--){
|
||||
if(arr[j]>arr[i]){
|
||||
swap(arr,j,i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
reverse(arr,i+1,n-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,6 @@ int main()
|
|||
for(int i=0;i<fac;++i){
|
||||
printf("rank %d :",i);
|
||||
printArr(a,n);
|
||||
nextArrangement(a,n);
|
||||
nextPermutation(a,n);
|
||||
}
|
||||
}
|
20
sort/quickSort.c
Normal file
20
sort/quickSort.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
int partition(int *arr,int i,int j)
|
||||
{
|
||||
int pivot = arr[j],p=i,q=j;
|
||||
while(p<q){
|
||||
while(p<q && arr[p]<=pivot)++p;
|
||||
if(p<q)arr[q--]=arr[p];
|
||||
while(p<q && arr[q]>pivot)--q;
|
||||
if(p<q)arr[p++]=arr[q];
|
||||
}
|
||||
arr[p]=pivot;
|
||||
return p;
|
||||
}
|
||||
void quickSort(int *arr,int i,int j)
|
||||
{
|
||||
if(i<j){
|
||||
int p = partition(arr,i,j);
|
||||
quickSort(arr,i,p-1);
|
||||
quickSort(arr,p+1,j);
|
||||
}
|
||||
}
|
|
@ -2,16 +2,12 @@ README = r'''
|
|||
# Algorithm
|
||||
>Notes and codes for learning algorithm and data structures :smiley:
|
||||
|
||||
Some pictures and ideas are from `<<Introduction to Algotithm>>
|
||||
Some pictures and ideas are from `<<Introduction to Algotithm>>`
|
||||
|
||||
I use python 3.6+ and c++ to implements them.
|
||||
Since I used f-Strings in python, you may use python 3.6+ to run the following python scripts.
|
||||
|
||||
>>I am still learning new things and this repo is always updating.
|
||||
I use python 3.6+ and c/c++ to implement them.
|
||||
|
||||
# Notice
|
||||
Currently, Github can't render latex math formulas.
|
||||
So,if you wannt to view the notes which contain latex math formulas and are in markdown format, you can visit [my blog](https://mbinary.coding.me)
|
||||
Currently, Github can't render latex math formulas.Thus,if you want to view the markodwn notes which contain latex math formulas, you can visit [my blog](https://mbinary.coding.me)
|
||||
|
||||
# Index
|
||||
{index}
|
||||
|
|
Loading…
Reference in New Issue
Block a user