forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
34 changed files
with
1,592 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,133 +1,70 @@ | ||
from typing import Optional | ||
|
||
|
||
# | ||
# 1) Insertion, deletion and random access of array | ||
# 2) Assumes int for element type | ||
# | ||
# Author: Wenru | ||
# | ||
|
||
|
||
class MyArray: | ||
"""A simple wrapper around List. | ||
You cannot have -1 in the array. | ||
""" | ||
|
||
def __init__(self, capacity: int): | ||
|
||
self._data = [] | ||
self._count = 0 | ||
self._capacity = capacity | ||
|
||
def __getitem__(self, position: int) -> int: | ||
|
||
"""Support for subscript. | ||
Perhaps better than the find() method below. | ||
""" | ||
def __getitem__(self, position: int) -> object: | ||
return self._data[position] | ||
|
||
def find(self, index: int) -> Optional[int]: | ||
def __setitem__(self, index: int, value: object): | ||
self._data[index] = value | ||
|
||
if index >= self._count or index <= -self._count: | ||
def __len__(self) -> int: | ||
return len(self._data) | ||
|
||
def __iter__(self): | ||
for item in self._data: | ||
yield item | ||
|
||
def find(self, index: int) -> object: | ||
try: | ||
return self._data[index] | ||
except IndexError: | ||
return None | ||
return self._data[index] | ||
|
||
def delete(self, index: int) -> bool: | ||
|
||
if index >= self._count or index <= -self._count: | ||
try: | ||
self._data.pop(index) | ||
return True | ||
except IndexError: | ||
return False | ||
|
||
self._data[index:-1] = self._data[index + 1:] | ||
self._count -= 1 | ||
# 真正将数据删除并覆盖原来的数据 ,这个需要增加 | ||
self._data = self._data[0:self._count] | ||
print('delete function', self._data) | ||
return True | ||
|
||
def insert(self, index: int, value: int) -> bool: | ||
|
||
# if index >= self._count or index <= -self._count: return False | ||
if self._capacity == self._count: | ||
return False | ||
# 如果还有空间,那么插入位置大于当前的元素个数,可以插入最后的位置 | ||
if index >= self._count: | ||
self._data.append(value) | ||
# 同上,如果位置小于0 可以插入第0个位置. | ||
if index < 0: | ||
print(index) | ||
self._data.insert(0, value) | ||
|
||
self._count += 1 | ||
return True | ||
|
||
def insert_v2(self, index: int, value: int) -> bool: | ||
""" | ||
支持任意位置插入 | ||
:param index: | ||
:param value: | ||
:return: | ||
""" | ||
# 数组空间已满 | ||
if self._capacity == self._count: | ||
return False | ||
|
||
# 插入位置大于当前的元素个数,可以插入最后的位置 | ||
if index >= self._count: | ||
self._data.append(value) | ||
elif index < 0: | ||
# 位置小于 0 可以插入第 0 个位置 | ||
self._data.insert(0, value) | ||
else: | ||
# 挪动 index 至 _count 位到 index+1 至 _count+1 位 | ||
# 插入第 index | ||
self._data[index+1:self._count+1] = self._data[index:self._count] | ||
self._data[index] = value | ||
|
||
self._count += 1 | ||
return True | ||
|
||
def insert_to_tail(self, value: int) -> bool: | ||
|
||
if self._count == self._capacity: | ||
if len(self) >= self._capacity: | ||
return False | ||
if self._count == len(self._data): | ||
self._data.append(value) | ||
else: | ||
self._data[self._count] = value | ||
self._count += 1 | ||
return True | ||
|
||
def __repr__(self) -> str: | ||
|
||
return " ".join(str(num) for num in self._data[:self._count]) | ||
return self._data.insert(index, value) | ||
|
||
def print_all(self): | ||
|
||
for num in self._data[:self._count]: | ||
print(f"{num}", end=" ") | ||
print("\n", flush=True) | ||
for item in self: | ||
print(item) | ||
|
||
|
||
def test_myarray(): | ||
array_a = MyArray(6) | ||
for num in range(6): | ||
array_a.insert_to_tail(num) | ||
assert array_a.find(0) == 0 | ||
assert array_a[0] == 0 | ||
array_a.delete(0) | ||
assert array_a[0] == 1 | ||
array = MyArray(5) | ||
array.insert(0, 3) | ||
array.insert(0, 4) | ||
array.insert(1, 5) | ||
array.insert(3, 9) | ||
array.insert(3, 10) | ||
assert array.insert(0, 100) is False | ||
assert len(array) == 5 | ||
assert array.find(1) == 5 | ||
assert array.delete(4) is True | ||
array.print_all() | ||
|
||
|
||
if __name__ == "__main__": | ||
a = MyArray(6) | ||
for i in range(6): | ||
a.insert_to_tail(i) | ||
a.delete(2) | ||
print(a) | ||
a.insert_to_tail(7) | ||
print(a) | ||
print('origin', a) | ||
a.delete(4) | ||
print('delete ', a) | ||
|
||
a.insert(100, 10000) | ||
print(a) | ||
test_myarray() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#!/usr/bin/python | ||
# -*- coding: UTF-8 -*- | ||
|
||
inversion_num = 0 | ||
|
||
|
||
def merge_sort_counting(nums, start, end): | ||
if start >= end: | ||
return | ||
|
||
mid = (start + end)//2 | ||
merge_sort_counting(nums, start, mid) | ||
merge_sort_counting(nums, mid+1, end) | ||
merge(nums, start, mid, end) | ||
|
||
|
||
def merge(nums, start, mid, end): | ||
global inversion_num | ||
i = start | ||
j = mid+1 | ||
tmp = [] | ||
while i <= mid and j <= end: | ||
if nums[i] <= nums[j]: | ||
inversion_num += j - mid - 1 | ||
tmp.append(nums[i]) | ||
i += 1 | ||
else: | ||
tmp.append(nums[j]) | ||
j += 1 | ||
|
||
while i <= mid: | ||
# 这时nums[i]的逆序数是整个nums[mid+1: end+1]的长度 | ||
inversion_num += end - mid | ||
tmp.append(nums[i]) | ||
i += 1 | ||
|
||
while j <= end: | ||
tmp.append(nums[j]) | ||
j += 1 | ||
|
||
nums[start: end+1] = tmp | ||
|
||
|
||
if __name__ == '__main__': | ||
print('--- count inversion number using merge sort ---') | ||
# nums = [5, 0, 4, 2, 3, 1, 6, 8, 7] | ||
nums = [5, 0, 4, 2, 3, 1, 3, 3, 3, 6, 8, 7] | ||
print('nums : {}'.format(nums)) | ||
merge_sort_counting(nums, 0, len(nums)-1) | ||
print('sorted: {}'.format(nums)) | ||
print('inversion number: {}'.format(inversion_num)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#!/usr/bin/python | ||
# -*- coding: UTF-8 -*- | ||
|
||
from typing import List | ||
|
||
# 背包选取的物品列表 | ||
picks = [] | ||
picks_with_max_value = [] | ||
|
||
|
||
def bag(capacity: int, cur_weight: int, items_info: List, pick_idx: int): | ||
""" | ||
回溯法解01背包,穷举 | ||
:param capacity: 背包容量 | ||
:param cur_weight: 背包当前重量 | ||
:param items_info: 物品的重量和价值信息 | ||
:param pick_idx: 当前物品的索引 | ||
:return: | ||
""" | ||
# 考察完所有物品,或者在中途已经装满 | ||
if pick_idx >= len(items_info) or cur_weight == capacity: | ||
global picks_with_max_value | ||
if get_value(items_info, picks) > \ | ||
get_value(items_info, picks_with_max_value): | ||
picks_with_max_value = picks.copy() | ||
else: | ||
item_weight = items_info[pick_idx][0] | ||
if cur_weight + item_weight <= capacity: # 选 | ||
picks[pick_idx] = 1 | ||
bag(capacity, cur_weight + item_weight, items_info, pick_idx + 1) | ||
|
||
picks[pick_idx] = 0 # 不选 | ||
bag(capacity, cur_weight, items_info, pick_idx + 1) | ||
|
||
|
||
def get_value(items_info: List, pick_items: List): | ||
values = [_[1] for _ in items_info] | ||
return sum([a*b for a, b in zip(values, pick_items)]) | ||
|
||
|
||
if __name__ == '__main__': | ||
# [(weight, value), ...] | ||
items_info = [(3, 5), (2, 2), (1, 4), (1, 2), (4, 10)] | ||
capacity = 8 | ||
|
||
print('--- items info ---') | ||
print(items_info) | ||
|
||
print('\n--- capacity ---') | ||
print(capacity) | ||
|
||
picks = [0] * len(items_info) | ||
bag(capacity, 0, items_info, 0) | ||
|
||
print('\n--- picks ---') | ||
print(picks_with_max_value) | ||
|
||
print('\n--- value ---') | ||
print(get_value(items_info, picks_with_max_value)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/bin/python | ||
# -*- coding: UTF-8 -*- | ||
|
||
# 棋盘尺寸 | ||
BOARD_SIZE = 8 | ||
|
||
solution_count = 0 | ||
queen_list = [0] * BOARD_SIZE | ||
|
||
|
||
def eight_queens(cur_column: int): | ||
""" | ||
输出所有符合要求的八皇后序列 | ||
用一个长度为8的数组代表棋盘的列,数组的数字则为当前列上皇后所在的行数 | ||
:return: | ||
""" | ||
if cur_column >= BOARD_SIZE: | ||
global solution_count | ||
solution_count += 1 | ||
# 解 | ||
print(queen_list) | ||
else: | ||
for i in range(BOARD_SIZE): | ||
if is_valid_pos(cur_column, i): | ||
queen_list[cur_column] = i | ||
eight_queens(cur_column + 1) | ||
|
||
|
||
def is_valid_pos(cur_column: int, pos: int) -> bool: | ||
""" | ||
因为采取的是每列放置1个皇后的做法 | ||
所以检查的时候不必检查列的合法性,只需要检查行和对角 | ||
1. 行:检查数组在下标为cur_column之前的元素是否已存在pos | ||
2. 对角:检查数组在下标为cur_column之前的元素,其行的间距pos - QUEEN_LIST[i] | ||
和列的间距cur_column - i是否一致 | ||
:param cur_column: | ||
:param pos: | ||
:return: | ||
""" | ||
i = 0 | ||
while i < cur_column: | ||
# 同行 | ||
if queen_list[i] == pos: | ||
return False | ||
# 对角线 | ||
if cur_column - i == abs(pos - queen_list[i]): | ||
return False | ||
i += 1 | ||
return True | ||
|
||
|
||
if __name__ == '__main__': | ||
print('--- eight queens sequence ---') | ||
eight_queens(0) | ||
|
||
print('\n--- solution count ---') | ||
print(solution_count) |
Oops, something went wrong.