├── README.md ├── datastructor1 ├── Backage.py ├── Huffman.py ├── JosephusRing.py ├── MergeSortedArray.py ├── SingleChain.py ├── TwoBranchTree.py ├── example.txt ├── find_oddnumber_in_array.py ├── get_number_of_1_in_binary.py ├── getmethods.py ├── no_operators_for_plus.py ├── string2number.py ├── stringunicode.py ├── tencent_2.py ├── 上楼梯递归.py ├── 两个栈实现的队列.py ├── 两个队列实现一个栈.py ├── 二进制运算相关.py ├── 可打印编码的霍夫曼树.py ├── 堆测试.py ├── 奇怪的表达式求值.py ├── 字符串全排列.py ├── 打印1到n之间的所有数字.py ├── 排序算法.py ├── 旋转数组求最小元素的值.py ├── 杨氏矩阵.py ├── 表达式互相转化.py ├── 调整数组顺序实现奇数在前偶数在后.py ├── 重建二叉树.py └── 霍夫曼树创建.py ├── datastructor2 ├── 1到n整数中出现1的总次数.py ├── Python单例模式.py ├── 丑数相关.py ├── 二叉树中和为某一个值的路径.py ├── 判断一棵二叉树是否为另一棵的子结构.py ├── 前序中序求后序.py ├── 包含min函数得栈.py ├── 合并两个有序链表.py ├── 堆和堆排序.py ├── 快速排序.py ├── 把数组排成最小的数.py ├── 数组中出现次数最多的那个元素的值.py ├── 栈的压入弹出序列合法性判断.py ├── 求1+2+到N.py ├── 求一可棵二叉树的镜像.py ├── 求两个链表的第一个公共节点.py ├── 连续子数组的最大和.py ├── 链表中倒数第K个数.py └── 顺时针打印矩阵.py ├── jingdong ├── 1.py ├── 2.py └── temp-2.py ├── mkreadme.py └── xiecheng └── 1.py /README.md: -------------------------------------------------------------------------------- 1 | # sword-to-offer 2 | 剑指Offer原书是用C++实现的,这里本人用Python对其中大部分使用了Python实现。 3 | 4 | 5 | 6 | ## README目录自动生成 7 | 因为文件数目略显臃肿,所以使用一个脚本来自动化生成了在GitHub上的链接。具体可以参考: 8 | 9 | - [自动化生成目录信息](https://github.com/guoruibiao/sword-to-offer/blob/master/mkreadme.py) 10 | - [自动化详细介绍](http://blog.csdn.net/marksinoberg/article/details/70175738) 11 | 12 | 13 | ## 声明 14 | 15 | 代码仅供参考,有哪些不恰当,不正确的地方,欢迎批评指正。(*^__^*) 谢谢…… 16 | 17 | --- 18 | ## 详细目录 19 | 20 | - [ 一个背包里面可以存放重量为weight的物品, 现有n件物品的集合s,其中质量分别为w0, w1,...wn-1.问能否从中选出若干物品,其和正好为weight 21 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/Backage.py) 22 | 23 | - [ 以O(1)空间复杂度找到O(n)数组中出现奇数的那个数的下标 24 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/find_oddnumber_in_array.py) 25 | 26 | - [ 获取一个模块或者类中的所有方法及参数列表 27 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/getmethods.py) 28 | 29 | - [ 输出数字的二进制中的1的个数; 判断一个数是否为2的幂 30 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/get_number_of_1_in_binary.py) 31 | 32 | - [ Python实现霍夫曼树 33 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/Huffman.py) 34 | 35 | - [ 约瑟夫环问题 36 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/JosephusRing.py) 37 | 38 | - [ 将两个排序的数组merge成新的排好序的数组 39 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/MergeSortedArray.py) 40 | 41 | - [ 没有加法运算符的加法实现, 没有减法运算符实现减法运算 42 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/no_operators_for_plus.py) 43 | 44 | - [ 单链表实现 45 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/SingleChain.py) 46 | 47 | - [ 将一个字符串转换成数字 48 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/string2number.py) 49 | 50 | - [ 无重复的字母组成的不同的串 51 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/stringunicode.py) 52 | 53 | - [ 腾讯笔试第二题,完美解决。类似于26进制的题型 54 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/tencent_2.py) 55 | 56 | - [ 二叉树相关所有内容 57 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/TwoBranchTree.py) 58 | 59 | - [ 一次可以1步,2步,3步,上10个台阶的所有可能的方法; 变态青蛙跳 60 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/上楼梯递归.py) 61 | 62 | - [ 使用两个栈构造一个队列 63 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/两个栈实现的队列.py) 64 | 65 | - [ 两个队列实现一个栈 66 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/两个队列实现一个栈.py) 67 | 68 | - [ 求一个数二进制中1的个数 69 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/二进制运算相关.py) 70 | 71 | - [ 别人实现的可打印编码的霍夫曼树 72 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/可打印编码的霍夫曼树.py) 73 | 74 | - [ 堆Python标准库的内置堆的测试! 75 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/堆测试.py) 76 | 77 | - [ 输入为一行字符串,即一个表达式。其中运算符只有-,+,*。参与计算的数字只有0~9. 78 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/奇怪的表达式求值.py) 79 | 80 | - [ 字符串全排列种类获取 81 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/字符串全排列.py) 82 | 83 | - [ 打印1到n位长度的所有数字,如n=2, 则打印1-99;n=3,打印1-999. 84 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/打印1到n之间的所有数字.py) 85 | 86 | - [Python实现的各种排序算法 87 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/排序算法.py) 88 | 89 | - [ 旋转数组求最小元素的值。如[3,4,5,1,2]是[1,2,3,4,5]数组的一个旋转。而且数组中的最小元素的值为1 90 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/旋转数组求最小元素的值.py) 91 | 92 | - [ 矩阵从左至右, 从上到下依次递增,求指定的一个数是否在此矩阵 93 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/杨氏矩阵.py) 94 | 95 | - [ 表达式转换,前缀中缀后缀 96 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/表达式互相转化.py) 97 | 98 | - [ 实现奇数在前偶数在后的数组调换。 99 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/调整数组顺序实现奇数在前偶数在后.py) 100 | 101 | - [ 根据前序遍历序列,中序遍历序列,重建一棵二叉树 102 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/重建二叉树.py) 103 | 104 | - [ 实现一个霍夫曼树 105 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor1/霍夫曼树创建.py) 106 | 107 | - [ 1到n整数中出现1的总次数。如输入12,包含1的有1,10,11,12.共5个1。 108 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/1到n整数中出现1的总次数.py) 109 | 110 | - [ 如果一个数的因子只是2,3,5,那么这个数被称为丑数。 111 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/丑数相关.py) 112 | 113 | - [ 二叉树中和为某一个值的路径 114 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/二叉树中和为某一个值的路径.py) 115 | 116 | - [ 判断一棵二叉树是否为另一棵的子结构,即子树。我的做法:遍历获取层次序列,判断序列是否在大树的序列中即可。 117 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/判断一棵二叉树是否为另一棵的子结构.py) 118 | 119 | - [ 根据前序遍历序列,中序遍历序列重建一棵二叉树 120 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/前序中序求后序.py) 121 | 122 | - [ 一个栈,实现min函数,并且min,pop,push操作的时间复杂度都得为O(1)。 123 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/包含min函数得栈.py) 124 | 125 | - [ 合并两个有序的链表。 126 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/合并两个有序链表.py) 127 | 128 | - [ 把数组排成最小的数 129 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/把数组排成最小的数.py) 130 | 131 | - [ 数组中出现次数最多的那个元素的值。如[1,2,3,4,5,6,2,2,2,2,27,8]结果为2 132 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/数组中出现次数最多的那个元素的值.py) 133 | 134 | - [ 栈的压入弹出序列合法性判断。如入栈:12345.出栈可以使45321,但是不能是43512 135 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/栈的压入弹出序列合法性判断.py) 136 | 137 | - [ 要求不使用乘除法,for,while,if,else,switch,case等关键字和三目运算实现这个和的运算。 138 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/求1+2+到N.py) 139 | 140 | - [ 堆和堆排序,默认使用大顶堆。 141 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/堆和堆排序.py) 142 | 143 | - [ 求一可棵二叉树的镜像 144 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/求一可棵二叉树的镜像.py) 145 | 146 | - [ 求两个链表的第一个公共节点。暴力法O(mn),所以空间换时间用栈特性,出栈的时候最后一个不等的节点就是公共节点了。 147 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/求两个链表的第一个公共节点.py) 148 | 149 | - [ 连续子数组的最大和 150 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/连续子数组的最大和.py) 151 | 152 | - [ 求出单链表中的倒数第K个节点的元素的值 153 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/链表中倒数第K个数.py) 154 | 155 | - [ 使用顺时针的方向打印一个矩阵。 156 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/datastructor2/顺时针打印矩阵.py) 157 | 158 | - [ 京东笔试第一题:求两个二进制数异或运算后的十进制的结果 159 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/jingdong/1.py) 160 | 161 | - [ 京东笔试第二题,没思路。(⊙﹏⊙)b 162 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/jingdong/2.py) 163 | 164 | - [ 临时测试文件,测完即可删除 165 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/jingdong/temp-2.py) 166 | 167 | - [ 携程笔试第一题题解思路 168 | ](https://github.com/guoruibiao/sword-to-offer/blob/master/xiecheng/1.py) 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /datastructor1/Backage.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: Backage.py 5 | # @Time: 2017/4/6 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 一个背包里面可以存放重量为weight的物品, 现有n件物品的集合s,其中质量分别为w0, w1,...wn-1.问能否从中选出若干物品,其和正好为weight 9 | 10 | def compute(weight, items, n): 11 | if weight == 0: 12 | return True 13 | if weight < 0 or n <0 or n > len(items): 14 | return False 15 | if compute((weight-items[n-1]), items, n-1): 16 | print("Item: {}".format(items[n-1])) 17 | return True 18 | if compute(weight, items, n - 1): 19 | return True 20 | else: 21 | return False 22 | 23 | def compute2(weight, items, n): 24 | if weight == 0: 25 | return True 26 | if weight < 0 or n <0 or n > len(items): 27 | return False 28 | if compute(weight, items, n - 1): 29 | return True 30 | if compute((weight-items[n]), items, n-1): 31 | print("Item: {}".format(items[n])) 32 | return True 33 | 34 | if __name__ == '__main__': 35 | items = [1,2,3,4,5,6,7,8,9] 36 | weight = 31 37 | compute(weight, items, len(items)) 38 | print('--------------------------') 39 | compute2(weight, items, len(items)) -------------------------------------------------------------------------------- /datastructor1/Huffman.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | # @Description: Python实现霍夫曼树 3 | 4 | import random 5 | 6 | 7 | # 定义节点 8 | class Node: 9 | def __init__(self, weight=0, left=None, right=None): 10 | self.weight = weight 11 | self.left = left 12 | self.right = right 13 | 14 | 15 | # 按权值排序 16 | def sort(list): 17 | return sorted(list, key=lambda node: node.weight) 18 | 19 | 20 | # 构建哈夫曼树 21 | def Huffman(list): 22 | while len(list) != 1: 23 | a, b = list[0], list[1] 24 | new = Node() 25 | new.weight = a.weight + b.weight 26 | new.left, new.right = a, b 27 | list.remove(a) 28 | list.remove(b) 29 | list.append(new) 30 | list = sort(list) 31 | return list 32 | 33 | 34 | # 中序遍历 35 | def traval(First): 36 | if First == None: return 37 | print(First.weight) 38 | traval(First.left) 39 | traval(First.right) 40 | 41 | 42 | # 获得树的长度 43 | def get_height(node): 44 | if node.left == None and node.right == None: return 1 45 | return get_height(node.left) + get_height(node.right) 46 | 47 | 48 | if __name__ == '__main__': 49 | list = [] 50 | 51 | for i in range(1, 11): 52 | list.append(Node(i)) 53 | 54 | list = sort(list) 55 | 56 | head = Huffman(list)[0] 57 | traval(head) 58 | -------------------------------------------------------------------------------- /datastructor1/JosephusRing.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: JosephusRing.py 5 | # @Time: 2017/4/5 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 约瑟夫环问题 9 | 10 | def notnonenumber(total): 11 | counter = 0 12 | for item in total: 13 | if item is not None: 14 | counter += 1 15 | return counter 16 | 17 | def josephus(total, k): 18 | index = 0 19 | while notnonenumber(total)!= 1: 20 | index = (k + index) %len(total) 21 | print("我{}先出去了!".format(total[index])) 22 | total.remove(total[index]) 23 | return total 24 | 25 | if __name__ == '__main__': 26 | ls = [1,2,3,4,5,6,7,8,9,10] 27 | result = josephus(ls, 3-1) 28 | print('最后就剩下老子{}了!'.format(result)) 29 | 30 | -------------------------------------------------------------------------------- /datastructor1/MergeSortedArray.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: MergeSortedArray.py 5 | # @Time: 2017/4/15 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 将两个排序的数组merge成新的排好序的数组 9 | 10 | def merge(arr1, arr2): 11 | result = [] 12 | arr1len = len(arr1) 13 | arr2len = len(arr2) 14 | minlen = min(arr1len, arr2len) 15 | 16 | for index in range(minlen): 17 | temp1, temp2 = arr1[index], 18 | 19 | 20 | 21 | 22 | if __name__ == '__main__': 23 | arr1 = [1,3,5,7,9] 24 | arr2 = [2,4,6,8,10] 25 | result = merge(arr1, arr2) 26 | print(result) 27 | -------------------------------------------------------------------------------- /datastructor1/SingleChain.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: SingleChain.py 5 | # @Time: 2017/4/5 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 单链表实现 9 | 10 | class Node(object): 11 | def __init__(self, data, next): 12 | self.data = data 13 | self.next = next 14 | 15 | class LianBiao(object): 16 | 17 | def __init__(self): 18 | self.root = None 19 | 20 | # 给单链表添加元素节点 21 | def addNode(self, data): 22 | if self.root==None: 23 | self.root = Node(data=data, next=None) 24 | return self.root 25 | else: 26 | # 有头结点,则需要遍历到尾部节点,进行链表增加操作 27 | cursor = self.root 28 | while cursor.next!= None: 29 | cursor = cursor.next 30 | cursor.next = Node(data=data, next=None) 31 | return self.root 32 | 33 | # 在链表的尾部添加新节点,底层调用addNode方法即可 34 | def append(self, value): 35 | self.addNode(data=value) 36 | 37 | # 在链表首部添加节点 38 | def prepend(self, value): 39 | if self.root == None: 40 | self.root = Node(value, None) 41 | else: 42 | newroot = Node(value, None) 43 | # 更新root索引 44 | newroot.next = self.root 45 | self.root = newroot 46 | 47 | # 在链表的指定位置添加节点 48 | def insert(self, index, value): 49 | if self.root == None: 50 | return 51 | if index<=0 or index >self.size(): 52 | print('index %d 非法, 应该审视一下您的插入节点在整个链表的位置!') 53 | return 54 | elif index==1: 55 | # 如果index==1, 则在链表首部添加即可 56 | self.prepend(value) 57 | elif index == self.size()+1: 58 | # 如果index正好比当前链表长度大一,则添加在尾部即可 59 | self.append(value) 60 | else: 61 | # 如此,在链表中部添加新节点,直接进行添加即可。需要使用计数器来维护插入未知 62 | counter = 2 63 | pre = self.root 64 | cursor = self.root.next 65 | while cursor!=None: 66 | if counter == index: 67 | temp = Node(value, None) 68 | pre.next = temp 69 | temp.next = cursor 70 | break 71 | else: 72 | counter += 1 73 | pre = cursor 74 | cursor = cursor.next 75 | 76 | # 删除指定位置上的节点 77 | def delNode(self, index): 78 | if self.root == None: 79 | return 80 | if index<=0 or index > self.size(): 81 | return 82 | # 对第一个位置需要小心处理 83 | if index == 1: 84 | self.root = self.root.next 85 | else: 86 | pre = self.root 87 | cursor = pre.next 88 | counter = 2 89 | while cursor!= None: 90 | if index == counter: 91 | print('can be here!') 92 | pre.next = cursor.next 93 | break 94 | else: 95 | pre = cursor 96 | cursor = cursor.next 97 | counter += 1 98 | 99 | # 删除值为value的链表节点元素 100 | def delValue(self, value): 101 | if self.root == None: 102 | return 103 | # 对第一个位置需要小心处理 104 | if self.root.data == value: 105 | self.root = self.root.next 106 | else: 107 | pre = self.root 108 | cursor = pre.next 109 | while cursor!=None: 110 | if cursor.data == value: 111 | pre.next = cursor.next 112 | # 千万记得更新这个节点,否则会出现死循环。。。 113 | cursor = cursor.next 114 | continue 115 | else: 116 | pre = cursor 117 | cursor = cursor.next 118 | 119 | # 判断链表是否为空 120 | def isempty(self): 121 | if self.root == None or self.size()==0: 122 | return True 123 | else: 124 | return False 125 | 126 | # 删除链表及其内部所有元素 127 | def truncate(self): 128 | if self.root == None or self.size()==0: 129 | return 130 | else: 131 | cursor = self.root 132 | while cursor!= None: 133 | cursor.data = None 134 | cursor = cursor.next 135 | self.root = None 136 | cursor = None 137 | 138 | # 获取指定位置的节点的值 139 | def getvalue(self, index): 140 | if self.root is None or self.size()==0: 141 | print('当前链表为空!') 142 | return None 143 | if index<=0 or index>self.size(): 144 | print("index %d不合法!"%index) 145 | return None 146 | else: 147 | counter = 1 148 | cursor = self.root 149 | while cursor is not None: 150 | if index == counter: 151 | return cursor.data 152 | else: 153 | counter += 1 154 | cursor = cursor.next 155 | 156 | # 获取链表尾部的值,且不删除该尾部节点 157 | def peek(self): 158 | return self.getvalue(self.size()) 159 | 160 | # 获取链表尾部节点的值,并删除该尾部节点 161 | def pop(self): 162 | if self.root is None or self.size()==0: 163 | print('当前链表已经为空!') 164 | return None 165 | elif self.size()==1: 166 | top = self.root.data 167 | self.root = None 168 | return top 169 | else: 170 | pre = self.root 171 | cursor = pre.next 172 | while cursor.next is not None: 173 | pre = cursor 174 | cursor = cursor.next 175 | top = cursor.data 176 | cursor = None 177 | pre.next = None 178 | return top 179 | 180 | # 单链表逆序实现 181 | def reverse(self): 182 | if self.root is None: 183 | return 184 | if self.size()==1: 185 | return 186 | else: 187 | # post = None 188 | pre = None 189 | cursor = self.root 190 | while cursor is not None: 191 | # print('逆序操作逆序操作') 192 | post = cursor.next 193 | cursor.next = pre 194 | pre = cursor 195 | cursor = post 196 | # 千万不要忘记了把逆序后的头结点赋值给root,否则无法正确显示 197 | self.root = pre 198 | 199 | # 删除链表中的重复元素 200 | def delDuplecate(self): 201 | # 使用一个map来存放即可,类似于变形的“桶排序” 202 | dic = {} 203 | if self.root == None: 204 | return 205 | if self.size() == 1: 206 | return 207 | pre = self.root 208 | cursor = pre.next 209 | dic = {} 210 | # 为字典赋值 211 | temp = self.root 212 | while temp!=None: 213 | dic[str(temp.data)] = 0 214 | temp = temp.next 215 | temp = None 216 | # 开始实施删除重复元素的操作 217 | while cursor!=None: 218 | if dic[str(cursor.data)] == 1: 219 | pre.next = cursor.next 220 | cursor = cursor.next 221 | else: 222 | dic[str(cursor.data)] += 1 223 | pre = cursor 224 | cursor = cursor.next 225 | 226 | 227 | # 修改指定位置节点的值 228 | def updateNode(self, index, value): 229 | if self.root == None: 230 | return 231 | if index<0 or index>self.size(): 232 | return 233 | if index == 1: 234 | self.root.data = value 235 | return 236 | else: 237 | cursor = self.root.next 238 | counter = 2 239 | while cursor!=None: 240 | if counter == index: 241 | cursor.data = value 242 | break 243 | cursor = cursor.next 244 | counter += 1 245 | 246 | 247 | # 获取单链表的大小 248 | def size(self): 249 | counter = 0 250 | if self.root == None: 251 | return counter 252 | else: 253 | cursor = self.root 254 | while cursor!=None: 255 | counter +=1 256 | cursor = cursor.next 257 | return counter 258 | 259 | 260 | # 打印链表自身元素 261 | def print(self): 262 | if(self.root==None): 263 | return 264 | else: 265 | cursor = self.root 266 | while cursor!=None: 267 | print(cursor.data, end='\t') 268 | cursor = cursor.next 269 | print() 270 | 271 | 272 | if __name__ == '__main__': 273 | # 创建一个链表对象 274 | lianbiao = LianBiao() 275 | # 判断当前链表是否为空 276 | print("链表为空%d"%lianbiao.isempty()) 277 | # 判断当前链表是否为空 278 | lianbiao.addNode(1) 279 | print("链表为空%d"%lianbiao.isempty()) 280 | # 添加一些节点,方便操作 281 | lianbiao.addNode(2) 282 | lianbiao.addNode(3) 283 | lianbiao.addNode(4) 284 | lianbiao.addNode(6) 285 | lianbiao.addNode(5) 286 | lianbiao.addNode(6) 287 | lianbiao.addNode(7) 288 | lianbiao.addNode(3) 289 | # 打印当前链表所有值 290 | print('打印当前链表所有值') 291 | lianbiao.print() 292 | # 测试对链表求size的操作 293 | print("链表的size: "+str(lianbiao.size())) 294 | # 测试指定位置节点值的获取 295 | print('测试指定位置节点值的获取') 296 | print(lianbiao.getvalue(1)) 297 | print(lianbiao.getvalue(lianbiao.size())) 298 | print(lianbiao.getvalue(7)) 299 | # 测试删除链表中指定值, 可重复性删除 300 | print('测试删除链表中指定值, 可重复性删除') 301 | lianbiao.delNode(4) 302 | lianbiao.print() 303 | lianbiao.delValue(3) 304 | lianbiao.print() 305 | # 去除链表中的重复元素 306 | print('去除链表中的重复元素') 307 | lianbiao.delDuplecate() 308 | lianbiao.print() 309 | # 指定位置的链表元素的更新测试 310 | print('指定位置的链表元素的更新测试') 311 | lianbiao.updateNode(6, 99) 312 | lianbiao.print() 313 | # 测试在链表首部添加节点 314 | print('测试在链表首部添加节点') 315 | lianbiao.prepend(77) 316 | lianbiao.prepend(108) 317 | lianbiao.print() 318 | # 测试在链表尾部添加节点 319 | print('测试在链表尾部添加节点') 320 | lianbiao.append(99) 321 | lianbiao.append(100) 322 | lianbiao.print() 323 | # 测试指定下标的插入操作 324 | print('测试指定下标的插入操作') 325 | lianbiao.insert(1, 10010) 326 | lianbiao.insert(3, 333) 327 | lianbiao.insert(lianbiao.size(), 99999) 328 | lianbiao.print() 329 | # 测试peek 操作 330 | print('测试peek 操作') 331 | print(lianbiao.peek()) 332 | lianbiao.print() 333 | # 测试pop 操作 334 | print('测试pop 操作') 335 | print(lianbiao.pop()) 336 | lianbiao.print() 337 | # 测试单链表的逆序输出 338 | print('测试单链表的逆序输出') 339 | lianbiao.reverse() 340 | lianbiao.print() 341 | # 测试链表的truncate操作 342 | print('测试链表的truncate操作') 343 | lianbiao.truncate() 344 | lianbiao.print() 345 | -------------------------------------------------------------------------------- /datastructor1/TwoBranchTree.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: TwoBranchTree.py 5 | # @Time: 2017/4/6 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 二叉树相关所有内容 9 | 10 | # 创建二叉树节点 11 | class Node(object): 12 | def __init__(self, data, left, right): 13 | self.data = data 14 | self.left = None 15 | self.right = None 16 | 17 | # 创建二叉树 18 | class Tree(object): 19 | # 创建一棵树,默认会有一个根节点 20 | def __init__(self, data): 21 | self.root = Node(data, None, None) 22 | self.size = 1 23 | 24 | ##########################################################为了计算二叉树的宽度而用 25 | # 存放各层节点数目 26 | self.n = [] 27 | # 初始化层,否则列表访问无效 28 | for item in range(pow(2, 5)): 29 | self.n.append(0) 30 | # 索引标识 31 | self.maxwidth = 0 32 | self.i = 0 33 | 34 | 35 | # 求二叉树包含的节点数目 36 | def getsize(self): 37 | stack = [self.root] 38 | # 为了正确获取数目,这里需要先初始化一下 39 | self.size = 0 40 | while stack: 41 | temp = stack.pop(0) 42 | self.size += 1 43 | if temp.left: 44 | stack.append(temp.left) 45 | if temp.right: 46 | stack.append(temp.right) 47 | return self.size 48 | 49 | # 默认以层次遍历打印出该二叉树 50 | def print(self): 51 | stack = [self.root] 52 | while stack: 53 | temp = stack.pop(0) 54 | print(str(temp.data)+"\t", end='\t') 55 | if temp.left: 56 | stack.append(temp.left) 57 | if temp.right: 58 | stack.append(temp.right) 59 | # 递归实现前序遍历 60 | def qianxuDG(self, root): 61 | if root: 62 | print(root.data) 63 | self.qianxuDG(root.left) 64 | self.qianxuDG(root.right) 65 | 66 | # 递归实现中序遍历 67 | def zhongxuDG(self, root): 68 | if root: 69 | self.zhongxuDG(root.left) 70 | print(root.data) 71 | self.zhongxuDG(root.right) 72 | 73 | # 求得二叉树的最大高度 74 | def height(self, root): 75 | if not root: 76 | return 0 77 | ldeepth = self.height(root.left) 78 | rdeepth = self.height(root.right) 79 | return max(ldeepth+1, rdeepth+1) 80 | # 求得二叉树的最大深度 81 | def deepth(self, root): 82 | return self.height(root)-1 83 | # 递归实现后序遍历 84 | def houxuDG(self, root): 85 | if root: 86 | self.houxuDG(root.left) 87 | self.houxuDG(root.right) 88 | print(root.data) 89 | 90 | # 二叉树的先序遍历非递归实现 91 | def xianxu(self): 92 | """ 93 | 进栈向左走, 如果当前节点有右子树, 则先把右子树入栈,再把左子树入栈。来实现先根遍历效果 94 | :return: 95 | """ 96 | if self.root is None: 97 | return 98 | else: 99 | stack = [self.root] 100 | while stack: 101 | current = stack.pop() 102 | print(current.data) 103 | if current.right: 104 | stack.append(current.right) 105 | if current.left: 106 | stack.append(current.left) 107 | 108 | # 二叉树的中序非递归实现 109 | def zhongxu(self): 110 | if self.root is None: 111 | return 112 | else: 113 | # stack = [self.root] 114 | # current = stack[-1] 115 | stack = [] 116 | current = self.root 117 | while len(stack)!=0 or current: 118 | if current: 119 | stack.append(current) 120 | current = current.left 121 | else: 122 | temp = stack.pop() 123 | print(temp.data) 124 | current = temp.right 125 | 126 | # 二叉树的后序非递归实现 127 | def houxu(self): 128 | if self.root is None: 129 | return 130 | else: 131 | stack1 = [] 132 | stack2 = [] 133 | stack1.append(self.root) 134 | # 对每一个头结点进行判断,先将该头结点放到栈2中,如果该节点有左子树则放入栈1, 有右子树也放到栈1 135 | while stack1: 136 | current = stack1.pop() 137 | stack2.append(current) 138 | if current.left: 139 | stack1.append(current.left) 140 | if current.right: 141 | stack1.append(current.right) 142 | # 直接遍历输出stack2即可 143 | while stack2: 144 | print(stack2.pop().data) 145 | 146 | # 求一颗二叉树的最大宽度 147 | def width(self, root): 148 | if root is None: 149 | return 150 | else: 151 | # 如果是访问根节点 152 | if self.i == 0: 153 | # 第一层加一 154 | self.n[0] =1 155 | # 到达第二层 156 | self.i += 1 157 | if root.left: 158 | self.n[self.i] += 1 159 | if root.right: 160 | self.n[self.i] += 1 161 | # print('临时数据:', self.n) 162 | else: 163 | # 访问子树 164 | self.i += 1 165 | # print('二叉树所在层数:', self.i) 166 | if root.left: 167 | self.n[self.i] += 1 168 | if root.right: 169 | self.n[self.i] += 1 170 | # 开始判断, 取出最大值 171 | # maxwidth = max(maxwidth, n[i]) 172 | # maxwidth.append(max(max(maxwidth), n[i])) 173 | self.maxwidth= max(self.maxwidth, self.n[self.i]) 174 | # 遍历左子树 175 | self.width(root.left) 176 | # 往上退一层 177 | self.i -= 1 178 | # 遍历右子树 179 | self.width(root.right) 180 | 181 | return self.maxwidth 182 | 183 | 184 | if __name__ == '__main__': 185 | # 手动创建一课二叉树 186 | print('手动创建一课二叉树') 187 | tree = Tree(1) 188 | tree.root.left = Node(2, None, None) 189 | tree.root.right = Node(3, None, None) 190 | tree.root.left.left = Node(4, None, None) 191 | tree.root.left.right = Node(5, None, None) 192 | tree.root.right.left = Node(6, None, None) 193 | tree.root.right.right = Node(7, None, None) 194 | tree.root.left.left.left = Node(8, None, None) 195 | tree.root.left.left.right = Node(9, None, None) 196 | tree.root.left.right.left = Node(10, None, None) 197 | tree.root.left.right.left = Node(11, None, None) 198 | # 测试一下是否创建成功 199 | print('测试一下是否创建成功') 200 | print(tree.root.data) 201 | print(tree.root.left.data) 202 | print(tree.root.right.data) 203 | print(tree.root.left.left.data) 204 | print(tree.root.left.right.data) 205 | # 调用方法打印一下效果:以层次遍历实现 206 | print('调用方法打印一下效果:以层次遍历实现') 207 | tree.print() 208 | print('前序遍历递归实现') 209 | # 前序遍历递归实现 210 | tree.qianxuDG(tree.root) 211 | # 中序遍历递归实现 212 | print('中序遍历递归实现') 213 | tree.zhongxuDG(tree.root) 214 | # 后序遍历递归实现 215 | print('后序遍历递归实现') 216 | tree.houxuDG(tree.root) 217 | # 求取二叉树的高度 218 | print('求取二叉树的高度') 219 | print(tree.height(tree.root)) 220 | # 求取二叉树的深度 221 | print('求取二叉树的深度') 222 | print(tree.deepth(tree.root)) 223 | # 二叉树的非递归先序遍历实现 224 | print('二叉树的非递归先序遍历实现') 225 | tree.xianxu() 226 | print('中序非递归遍历测试') 227 | tree.zhongxu() 228 | print('后序非递归遍历测试') 229 | tree.houxu() 230 | print('二叉树的最大宽度为: {}'.format(tree.width(tree.root))) 231 | print('二叉树的节点数目为: {}'.format(tree.getsize())) -------------------------------------------------------------------------------- /datastructor1/example.txt: -------------------------------------------------------------------------------- 1 | def hello(): 2 | print('hello world!') 3 | 4 | def show(name): 5 | print('hello %s'%name) -------------------------------------------------------------------------------- /datastructor1/find_oddnumber_in_array.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: find_oddnumber_in_array.py 5 | # @Time: 2017/4/13 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 以O(1)空间复杂度找到O(n)数组中出现奇数的那个数的下标 9 | 10 | def find(array): 11 | """ 12 | 仅适用于数据连在一起的情况,如ls = [1,1,2,2,3,3,4,4,5,5,6,6,7,8,8,9,9] 13 | :param array: 14 | :return: 15 | """ 16 | temp = array[0] 17 | index = 1 18 | while index= 2 23 | :param n: 24 | :return: 25 | """ 26 | if n == 1: 27 | return 1 28 | if n == 2: 29 | return 2 30 | index = 3 31 | total = 0 32 | while index <= n: 33 | total += 2*forgjump(n-1) 34 | index += 1 35 | return total 36 | 37 | 38 | if __name__ == '__main__': 39 | # print(run(10)) 40 | print(forgjump(3)) 41 | -------------------------------------------------------------------------------- /datastructor1/两个栈实现的队列.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 两个栈实现的队列.py 5 | # @Time: 2017/4/15 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 使用两个栈构造一个队列 9 | 10 | class Queue(object): 11 | """ 12 | 两个栈实现一个先进先出的队列 13 | """ 14 | def __init__(self): 15 | self.s1 = [] 16 | self.s2 = [] 17 | 18 | def enqueue(self, data): 19 | """ 20 | 入队列实现, 如果栈2中元素不为空,则把栈2中元素倒腾到栈1中,对栈1进行添加操作 21 | :param data: 22 | :return: 23 | """ 24 | while self.s2: 25 | self.s1.append(self.s2.pop()) 26 | self.s1.append(data) 27 | 28 | 29 | def dequeue(self): 30 | """ 31 | 出队列实现,如果栈1不为空,则把栈1中元素全部倒腾到栈2中,对栈2进行弹出操作 32 | :return: 33 | """ 34 | while self.s1: 35 | self.s2.append(self.s1.pop()) 36 | try: 37 | return self.s2.pop() 38 | except: 39 | print('队列空咯!') 40 | 41 | if __name__ == '__main__': 42 | queue = Queue() 43 | queue.enqueue(0) 44 | queue.enqueue(1) 45 | queue.enqueue(2) 46 | queue.enqueue(3) 47 | queue.enqueue(7) 48 | print(queue.dequeue()) 49 | print(queue.dequeue()) 50 | print(queue.dequeue()) 51 | print(queue.dequeue()) 52 | print(queue.dequeue()) 53 | print(queue.dequeue()) -------------------------------------------------------------------------------- /datastructor1/两个队列实现一个栈.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 两个队列实现一个栈.py 5 | # @Time: 2017/4/15 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 两个队列实现一个栈 9 | 10 | class Stack(object): 11 | 12 | def __init__(self): 13 | self.q1 = [] 14 | self.q2 = [] 15 | 16 | def pop(self): 17 | """ 18 | 出栈实现: 如果队列1中元素个数不为零,把队列1中的元素依次添加到队列2中,然后对于队列2从左至右往外取出数据即可。 19 | :return: 20 | """ 21 | while self.q1: 22 | self.q2.append(self.q1.pop(0)) 23 | try: 24 | return self.q2.pop() 25 | except: 26 | print("栈空咯!") 27 | 28 | def push(self, data): 29 | """ 30 | 入栈实现:如果队列2不为空,先把队列2中的元素从左至右依次添加到队列1的右边,然后再放入新的元素。 31 | :param data: 32 | :return: 33 | """ 34 | while self.q2: 35 | self.q1.append(self.q2.pop(0)) 36 | self.q1.append(data) 37 | 38 | if __name__ == '__main__': 39 | stack = Stack() 40 | stack.push(0) 41 | stack.push(1) 42 | stack.push(2) 43 | stack.push(3) 44 | print(stack.pop()) 45 | print(stack.pop()) 46 | print(stack.pop()) 47 | print(stack.pop()) 48 | print(stack.pop()) 49 | 50 | -------------------------------------------------------------------------------- /datastructor1/二进制运算相关.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 二进制运算相关.py 5 | # @Time: 2017/4/15 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 求一个数二进制中1的个数 9 | 10 | def rightscroll(n): 11 | """ 12 | 每次将数字与1相与运算,然后判断是不是1,之后把数字右移. 13 | 但是这种方式只适用于正数,否则对于负数右移后需要保留符号,最终会陷入死循环。 14 | :param n: 15 | :return: 16 | """ 17 | counter = 0 18 | while n: 19 | if n&1: 20 | counter += 1 21 | n = n >> 1 22 | return counter 23 | 24 | def leftscroll(n): 25 | """ 26 | 既然右移对于负数不成立,那么试试左移。移动判断标记来间接实现。 27 | 尴尬的是:并不能正确运行。。。 28 | :param n: 29 | :return: 30 | """ 31 | counter = 0 32 | flag = 1 33 | while flag: 34 | if n&flag: 35 | counter += 1 36 | flag = flag << 1 37 | return counter 38 | 39 | 40 | def advanced(n): 41 | """ 42 | 高级用法.实现求一个数的二进制表示法中1的个数。 43 | :param n: 44 | :return: 45 | """ 46 | counter = 0 47 | while n: 48 | counter += 1 49 | n = n&(n-1) 50 | return counter 51 | 52 | 53 | def isexpof2(n): 54 | """ 55 | 判断一个数是否为2的幂 56 | :param n: 57 | :return: 58 | """ 59 | return n&(n-1)==0 60 | 61 | 62 | def m2n(m, n): 63 | """ 64 | 给定的数m和n,求二者的二进制表示法,中经过几次可以变成一样的。 65 | 按照思路:先求出二进制,然后对比二者之间对应位置上数字不一致的个数,就是结果了 66 | :param m: 67 | :param n: 68 | :return: 69 | """ 70 | result = m^n 71 | counter = advanced(result) 72 | return counter 73 | 74 | if __name__ == '__main__': 75 | n = 0xFFFFFFFF 76 | # result = rightscroll(n) 77 | # result = leftscroll(n) 78 | # print(result) 79 | # result = advanced(n) 80 | # print(result) 81 | 82 | # result = isexpof2(7) 83 | # print(result) 84 | result = m2n(10, 13) 85 | print(result) -------------------------------------------------------------------------------- /datastructor1/可打印编码的霍夫曼树.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | # @Description: 别人实现的可打印编码的霍夫曼树 3 | 4 | import struct 5 | 6 | codeDict = {} # 全局字典key=字符,value=数字 7 | encodeDict = {} 8 | filename = None 9 | listForEveryByte = [] 10 | 11 | 12 | class Node: 13 | def __init__(self, right=None, left=None, parent=None, weight=0, charcode=None): 14 | self.right = right 15 | self.left = left 16 | self.parent = parent 17 | self.weight = weight 18 | self.charcode = charcode 19 | 20 | 21 | # 按权值排序 22 | def sort(list): 23 | return sorted(list, key=lambda node: node.weight) 24 | 25 | 26 | # 构建哈夫曼树 27 | def Huffman(listOfNode): 28 | listOfNode = sort(listOfNode) 29 | while len(listOfNode) != 1: 30 | a, b = listOfNode[0], listOfNode[1] 31 | new = Node() 32 | new.weight, new.left, new.right = a.weight + b.weight, a, b 33 | a.parent, b.parent = new, new 34 | listOfNode.remove(a), listOfNode.remove(b) 35 | listOfNode.append(new) 36 | listOfNode = sort(listOfNode) 37 | return listOfNode 38 | 39 | 40 | def inPutFile(): 41 | global filename 42 | global listForEveryByte 43 | filename = input("请输入要压缩的文件:") 44 | global codeDict 45 | with open(filename, 'rb') as f: 46 | data = f.read() 47 | for Byte in data: 48 | codeDict.setdefault(Byte, 0) # 每个字节出现的次数默认为0 49 | codeDict[Byte] += 1 50 | listForEveryByte.append(Byte) 51 | 52 | 53 | def outputCompressedFile(): 54 | global listForEveryByte 55 | fileString = "" 56 | with open(filename.split(".")[0] + ".jbj", "wb") as f: 57 | for Byte in listForEveryByte: 58 | fileString += encodeDict[Byte] # 构成一个长字符序列 59 | leng = len(fileString) 60 | more = 16 - leng % 16 61 | fileString = fileString + "0" * more # 空位用0补齐 62 | # print(fileString) 63 | 64 | leng = len(fileString) 65 | i, j = 0, 16 66 | while j <= leng: 67 | k = fileString[i:j] 68 | a = int(k, 2) 69 | # print(a) 70 | # print(repr(struct.pack(">H",a))) 71 | f.write(struct.pack(">H", a)) 72 | # f.write(str(a)) 73 | i = i + 16 74 | j = j + 16 75 | 76 | 77 | def encode(head, listOfNode): 78 | global encodeDict 79 | for e in listOfNode: 80 | ep = e 81 | encodeDict.setdefault(e.charcode, "") 82 | while ep != head: 83 | 84 | if ep.parent.left == ep: 85 | encodeDict[e.charcode] = "1" + encodeDict[e.charcode] 86 | else: 87 | encodeDict[e.charcode] = "0" + encodeDict[e.charcode] 88 | ep = ep.parent 89 | 90 | 91 | if __name__ == '__main__': 92 | inPutFile() 93 | listOfNode = [] 94 | for e in codeDict.keys(): 95 | listOfNode.append(Node(weight=codeDict[e], charcode=e)) 96 | head = Huffman(listOfNode)[0] # 构建哈夫曼树,head称为树的根节点 97 | encode(head, listOfNode) 98 | 99 | for i in encodeDict.keys(): 100 | print(i, encodeDict[i]) 101 | # outputCompressedFile() -------------------------------------------------------------------------------- /datastructor1/堆测试.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 堆测试.py 5 | # @Time: 2017/4/6 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 堆Python标准库的内置堆的测试! 9 | 10 | import heapq as hq 11 | ls = [] 12 | hq.heappush(ls, 1) 13 | hq.heappush(ls, 2) 14 | hq.heappush(ls, 3) 15 | print(hq.heappop(ls)) 16 | print(hq.heappop(ls)) 17 | print(hq.heappop(ls)) -------------------------------------------------------------------------------- /datastructor1/奇怪的表达式求值.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 奇怪的表达式求值.py 5 | # @Time: 2017/4/7 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 输入为一行字符串,即一个表达式。其中运算符只有-,+,*。参与计算的数字只有0~9. 9 | # 保证表达式都是合法的,排列规则如样例所示。从左往右依次计算即可,而且小易所在的世界没有除法, 10 | # 输入:3+5*7 输出: 56 11 | # 核心匹配公式:for times in range(len(s)-int((len(s)+1)/2)): 12 | 13 | operator = "+-*" 14 | 15 | def isnumber(a): 16 | return str(a).isalnum() 17 | 18 | def isoperator(a): 19 | return str(a) in operator 20 | # 核心匹配公式:for times in range(len(s)-int((len(s)+1)/2)): 21 | def compute(s): 22 | s = list(s) 23 | result = 0 24 | for times in range(len(s)-int((len(s)+1)/2)): 25 | a = s[0] 26 | op = s[1] 27 | b = s[2] 28 | result = eval(str(a) + str(op) + str(b)) 29 | s.pop(0) 30 | s.pop(0) 31 | s.pop(0) 32 | print(" 插入前:", s) 33 | s.insert(0, result) 34 | print(" 插入后:",s) 35 | return result 36 | 37 | if __name__ == '__main__': 38 | s = '3+5*7+2-7' 39 | result = compute(s) 40 | print(result) -------------------------------------------------------------------------------- /datastructor1/字符串全排列.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 字符串全排列.py 5 | # @Time: 2017/4/6 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 字符串全排列种类获取 9 | 10 | def run(s): 11 | result = [] 12 | s = list(s) 13 | digui(s, result, 0) 14 | return set(result) 15 | 16 | def digui(s, resultset, position): 17 | if position == len(s)-1: 18 | resultset.append("".join(s)) 19 | else: 20 | for index in range(0, len(s)): 21 | s[index], s[position] = s[position], s[index] 22 | digui(s, resultset, position+1) 23 | s[position], s[index] = s[index], s[position] 24 | 25 | if __name__ == '__main__': 26 | s = 'abc' 27 | result = run(s) 28 | print(result) -------------------------------------------------------------------------------- /datastructor1/打印1到n之间的所有数字.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 打印1到n之间的所有数字.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 打印1到n位长度的所有数字,如n=2, 则打印1-99;n=3,打印1-999. 9 | 10 | # TODO: 本题未完成,待修改! 11 | 12 | def run(n): 13 | if n <=0 : 14 | return 15 | ls = [] 16 | for index in range(10): 17 | ls[0] = str(index)+'0' 18 | printRecursively(ls, n, 0) 19 | del ls 20 | 21 | def printRecursively(ls, length, index): 22 | if index == length - 1: 23 | printNumber(ls) 24 | return 25 | for i in range(10): 26 | ls[index+1] = str(index)+"0" 27 | printRecursively(ls, length, index+1) 28 | 29 | def printNumber(ls): 30 | print(ls) 31 | 32 | if __name__ == '__main__': 33 | run(3) -------------------------------------------------------------------------------- /datastructor1/排序算法.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 排序算法.py 5 | # @Time: 2017/4/6 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description:Python实现的各种排序算法 9 | 10 | 11 | ############################################################快速排序 12 | def getleftposition(ls, left, right): 13 | temp = ls[left] 14 | while left < right: 15 | while left < right and ls[right]>=temp: 16 | right -= 1 17 | ls[left] = ls[right] 18 | 19 | while left< right and ls[left]<= temp: 20 | left += 1 21 | ls[right] = ls[left] 22 | ls[left] = temp 23 | return left 24 | 25 | def quicksort(ls, left, right): 26 | if left<=right: 27 | pivot = getleftposition(ls, left, right) 28 | quicksort(ls, left, pivot-1) 29 | quicksort(ls, pivot+1, right) 30 | 31 | ###########################################################################高级快速排序 32 | def quicksortadvanced(ls): 33 | return [] if ls == [] else quicksortadvanced([x for x in ls[1:] if x < ls[0]]) + [ls[0]] + quicksortadvanced([x for x in ls[1:] if x >=ls[0]]) 34 | 35 | ###########################################################冒泡排序 36 | def bubblesort(ls): 37 | for i in range(len(ls)-1): 38 | for j in range(0, len(ls)-i-1): 39 | if ls[j]>ls[j+1]: 40 | ls[j], ls[j+1] = ls[j+1], ls[j] 41 | 42 | 43 | ###########################################################冒泡排序改进版 44 | def bubblesort_advanced(ls): 45 | issorted = False 46 | for i in range(len(ls)-1): 47 | issorted = True 48 | for j in range(len(ls)-i-1): 49 | if ls[j]>ls[j+1]: 50 | issorted = False 51 | ls[j], ls[j+1] = ls[j+1], ls[j] 52 | if issorted: 53 | continue 54 | 55 | ########################################################### 直接选择排序 56 | def directselect(ls): 57 | for i in range(len(ls)): 58 | position = i 59 | minvalue = ls[position] 60 | for j in range(i, len(ls)): 61 | if minvalue > ls[j]: 62 | minvalue = ls[j] 63 | position = j 64 | if position!= i: ls[i], ls[position] = ls[position], ls[i] 65 | 66 | 67 | 68 | ########################################################### 桶排序: 有点失败,key按照了字典顺序排列,所以对于77和8 ,77会排列在前面 69 | def bulketsort(ls): 70 | # 保存最终的数据集 71 | result = [] 72 | # 用字典进行处理 73 | dic = {} 74 | for item in ls: 75 | dic[str(item)] = 0 76 | for item in ls: 77 | dic[str(item)] += 1 78 | dic = [(int(k),dic[k]) for k in sorted(dic.keys())] 79 | print(dic) 80 | for item in dic: 81 | key, times = int(item[0]), int(item[1]) 82 | for i in range(0, int(times)): 83 | result.append(key) 84 | # 返回最终的结果集 85 | return result 86 | ############################################################### 字典相关的处理 http://python.jobbole.com/85124/ 87 | 88 | if __name__ == '__main__': 89 | ls = [2,5,1,-9,77,6,-81,8,3,5,4] 90 | # quicksort(ls, 0, len(ls)-1) 91 | # print(ls) 92 | # bubblesort(ls) 93 | # print(ls) 94 | # bubblesort_advanced(ls) 95 | # print(ls) 96 | # directselect(ls) 97 | # print(ls) 98 | # ls = bulketsort(ls) 99 | # print(ls) 100 | ls = quicksortadvanced(ls) 101 | print(ls) 102 | -------------------------------------------------------------------------------- /datastructor1/旋转数组求最小元素的值.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 旋转数组求最小元素的值.py 5 | # @Time: 2017/4/15 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 旋转数组求最小元素的值。如[3,4,5,1,2]是[1,2,3,4,5]数组的一个旋转。而且数组中的最小元素的值为1 9 | 10 | def compute(ls): 11 | """ 12 | 对于旋转了0个单位的旋转数组,如[1,2,3,4,5]不会奏效,需要额外的处理。也即是对于此类特殊数组,采用顺序查找的方式解决。 13 | :param ls: 14 | :return: 15 | """ 16 | ## 特殊情况处理,如11101是01111的旋转,此时只能采用顺序查找的方法了 17 | if ls[0] <= ls[-1]: 18 | minvalue = ls[0] 19 | pointer = len(ls)-1 20 | while pointer>=1: 21 | minvalue = minvalue if minvalue maze[row-1][col-1]: 16 | return False 17 | 18 | for x in range(row): 19 | for y in range(col): 20 | if maze[x][y] == value: 21 | return True 22 | elif maze[x][y] < value: 23 | # x, y = x+1, y+1 # 一开始就错在了这里,因为内层循环是依次往后走的 24 | continue 25 | elif maze[x][y] > value: 26 | if maze[x-1][y] == value: 27 | return True 28 | if maze[x][y-1]==value: 29 | return True 30 | return False 31 | 32 | 33 | 34 | 35 | if __name__ == '__main__': 36 | maze = [ 37 | [1,2,8,9], 38 | [2,4,9,12], 39 | [4,7,10,13], 40 | [6,8,11,15] 41 | ] 42 | value = 5 43 | result = compute(maze, value) 44 | print("存在{}吗?{}".format(value, result)) 45 | -------------------------------------------------------------------------------- /datastructor1/表达式互相转化.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 表达式互相转化.py 5 | # @Time: 2017/4/6 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 表达式转换,前缀中缀后缀 9 | # 输入 a+b=c 输出(= (+ a b)) 10 | # 输入 a+b+c输出 (+(+ a b)c) 11 | # 输入a*b+2 输出 (+(* a b)2) 12 | 13 | # 判断是否为数字或者字母 14 | def isnumberoralpha(item): 15 | return str(item).isalnum() or str(item).isalpha() 16 | 17 | # 判断是否为操作符 18 | def isoperator(item): 19 | return item in ['+', '-', '*', '/'] 20 | 21 | # 将中缀表达式转化为后缀表达式 22 | def mid2post(mid): 23 | numstack = [] 24 | opstack = [] 25 | 26 | for item in mid: 27 | if isnumberoralpha(item): 28 | numstack.append(item) 29 | 30 | 31 | # 计算后缀表达式的值 + 2 * a b 32 | def compute_suffix(exp): 33 | exp = list(exp) 34 | print(exp) 35 | stack = [] 36 | result = 0 37 | while exp: 38 | curr = exp.pop() 39 | if isnumberoralpha(curr): 40 | stack.append(curr) 41 | if isoperator(curr): 42 | a = stack.pop() 43 | b = stack.pop() 44 | result = eval(str(a) + str(curr) + str(b)) 45 | exp.append(result) 46 | return result 47 | 48 | if __name__ == '__main__': 49 | # mid = 'a+b+c' 50 | # result = mid2post(mid) 51 | # print(result) 52 | suffix = '+217*' 53 | result = compute_suffix(suffix) 54 | print(result) -------------------------------------------------------------------------------- /datastructor1/调整数组顺序实现奇数在前偶数在后.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 调整数组顺序实现奇数在前偶数在后.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 实现奇数在前偶数在后的数组调换。 9 | 10 | def transfer(ls): 11 | """ 12 | 遍历方式 13 | :param ls: 14 | :return: 15 | """ 16 | if len(ls)==2: 17 | if ls[0]%2==0 and ls[1]%2 is not 0: 18 | ls[0], ls[1] = ls[1], ls[0] 19 | else: 20 | left = 0 21 | while left1: 51 | a, b = lists[0], lists[1] 52 | node = Node(value=int(a.value+b.value)) 53 | node.left, node.right = a, b 54 | lists.remove(a) 55 | lists.remove(b) 56 | lists.append(node) 57 | lists = sorted(lists, key=lambda node: node.value) 58 | return lists 59 | 60 | 61 | def scan(root): 62 | if root: 63 | queue = [root] 64 | while queue: 65 | current = queue.pop(0) 66 | print(current.value, end='\t') 67 | if current.left: 68 | queue.append(current.left) 69 | if current.right: 70 | queue.append(current.right) 71 | 72 | 73 | # 根据创建好的霍夫曼打印出相应的编码信息 74 | def computecode(root): 75 | current = root 76 | if current.left is None and current.right is None: 77 | current.charcode += str(current.value) 78 | if current.left: 79 | current.charcode += str('0') 80 | computecode(current.left) 81 | if current.right: 82 | current.charcode += str('1') 83 | computecode(current.right) 84 | 85 | def printcode(root): 86 | current = root 87 | while current: 88 | if current.left is None and current.right is None: 89 | print(current.charcode) 90 | if current.left: 91 | current = current.left 92 | if current.right: 93 | current = current.right 94 | 95 | 96 | 97 | if __name__ == '__main__': 98 | ls = [Node(i) for i in range(1, 5)] 99 | huffman = Huffman(items=ls) 100 | huffman.print() 101 | print('===================================, 下面的方式不正确的原因是ls已经被上面代码修改过了,需要重新设置一下!') 102 | lssl = [Node(i) for i in range(1, 5)] 103 | root = create_huffman_tree(lssl)[0] 104 | scan(root) 105 | print('编码结果获取') 106 | computecode(huffman.root) 107 | printcode(huffman.root) -------------------------------------------------------------------------------- /datastructor2/1到n整数中出现1的总次数.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 1到n整数中出现1的总次数.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 1到n整数中出现1的总次数。如输入12,包含1的有1,10,11,12.共5个1。 9 | 10 | def compute(n): 11 | """ 12 | 循环除以10,判断个位数是否为1. 13 | :param n: 14 | :return: 15 | """ 16 | total = 0 17 | for i in range(1, n+1): 18 | while i: 19 | if i%10 == 1: 20 | total += 1 21 | # 尤其注意Python中的除法是真除,即浮点数除法。 22 | i = int(i / 10) 23 | return total 24 | 25 | 26 | if __name__ == '__main__': 27 | n = 12 28 | result = compute(n) 29 | print(result) 30 | -------------------------------------------------------------------------------- /datastructor2/Python单例模式.py: -------------------------------------------------------------------------------- 1 | #coding: utf8 2 | 3 | #############################################################类实现单例模式 4 | class Singleton(object): 5 | __instance = None 6 | def __init__(cls, *args, **kwargs): 7 | pass 8 | 9 | def __new__(cls, *args, **kwargs): 10 | if Singleton.__instance is None: 11 | Singleton.__instance = super(Singleton, cls).__new__(cls, *args, **kwargs) 12 | return Singleton.__instance 13 | 14 | class MyClass(Singleton): 15 | def __init__(self): 16 | print("Myclass->init method is called!") 17 | 18 | ##############################################################使用装饰器实现的单例模式 19 | def singleton(cls): 20 | instance = {} 21 | def decorator(*args, **kwargs): 22 | if cls not in instance: 23 | instance[cls] = cls(*args, **kwargs) 24 | return instance[cls] 25 | return decorator 26 | 27 | @singleton 28 | class DecoratorClass(): 29 | def __init__(self): 30 | print("Decorator->init methed called!") 31 | 32 | 33 | if __name__ == '__main__': 34 | print("类实现的单例模式:") 35 | mc = MyClass() 36 | mc2 = MyClass() 37 | print(id(mc)) 38 | print(id(mc2)) 39 | print("装饰器实现的单例模式:") 40 | dc = DecoratorClass() 41 | dc2 = DecoratorClass() 42 | print(id(dc)) 43 | print(id(dc2)) 44 | -------------------------------------------------------------------------------- /datastructor2/丑数相关.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 丑数相关.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 如果一个数的因子只是2,3,5,那么这个数被称为丑数。 9 | 10 | def isUglyNumber(n): 11 | if n ==1: 12 | return True 13 | else: 14 | while n: 15 | n = int(n/2) 16 | while n: 17 | n = int(n/3) 18 | while n: 19 | n = int(n/5) 20 | return True if n == 1 else False 21 | 22 | def commonway(k): 23 | """ 24 | 求从大到小排列的第n个丑数。但是这样的计算效率简直低的不能再低了。所以不采取。 25 | :return: 26 | """ 27 | counter = 1 28 | target = None 29 | while counter<=k: 30 | for i in range(1000): 31 | if isUglyNumber(i): 32 | counter += 1 33 | print(target) 34 | target = i 35 | return target 36 | 37 | if __name__ == '__main__': 38 | result = commonway(10) 39 | print(result) 40 | print(pow(2, 1499)) 41 | 42 | -------------------------------------------------------------------------------- /datastructor2/二叉树中和为某一个值的路径.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 二叉树中和为某一个值的路径.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 二叉树中和为某一个值的路径 9 | 10 | # TODO 哈哈,失败的作品。 11 | 12 | class Node(object): 13 | def __init__(self, data=None, left=None, right=None): 14 | self.data = data 15 | self.left = left 16 | self.right = right 17 | 18 | class Tree(object): 19 | def __init__(self, data=None): 20 | self.root = Node(data, None, None) 21 | 22 | def levelscan(self): 23 | """ 24 | 层次遍历二叉树。也即是广度优先遍历二叉树。 25 | :return: 26 | """ 27 | if self.root is None: 28 | return 29 | else: 30 | queue = [self.root] 31 | while queue: 32 | temp = queue.pop(0) 33 | print(temp.data, end='\t') 34 | if temp.left: 35 | queue.append(temp.left) 36 | if temp.right: 37 | queue.append(temp.right) 38 | print() 39 | 40 | 41 | def run(root, currsum, value, inlist=[], outlist=[]): 42 | if root is not None: 43 | currsum += root.data 44 | inlist.append(root.data) 45 | if currsum < value: 46 | run(root.left, currsum, value, inlist, outlist) 47 | run(root.right, currsum, value, inlist, outlist) 48 | 49 | if currsum == value: 50 | if root.left is not None and root.right is not None: 51 | addlist = inlist 52 | outlist.extend(addlist) 53 | inlist.pop(len(inlist)-1) 54 | 55 | 56 | if __name__ == '__main__': 57 | tree = Tree(10) 58 | tree.root.left = Node(5) 59 | tree.root.right = Node(12) 60 | tree.root.left.left = Node(4) 61 | tree.root.left.right = Node(7) 62 | resultpath = [] 63 | inlist = [] 64 | run(tree.root, 10, 22,inlist, resultpath) 65 | print(resultpath) -------------------------------------------------------------------------------- /datastructor2/判断一棵二叉树是否为另一棵的子结构.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 判断一棵二叉树是否为另一棵的子结构.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 判断一棵二叉树是否为另一棵的子结构,即子树。我的做法:遍历获取层次序列,判断序列是否在大树的序列中即可。 9 | 10 | class Node(object): 11 | def __init__(self, data=None, left=None, right=None): 12 | self.data = data 13 | self.left = left 14 | self.right = right 15 | 16 | class Tree(object): 17 | def __init__(self, data=None): 18 | self.root = Node(data, None, None) 19 | 20 | def levelscan(self): 21 | """ 22 | 层次遍历二叉树。也即是广度优先遍历二叉树。 23 | :return: 24 | """ 25 | if self.root is None: 26 | return 27 | else: 28 | queue = [self.root] 29 | while queue: 30 | temp = queue.pop(0) 31 | print(temp.data, end='\t') 32 | if temp.left: 33 | queue.append(temp.left) 34 | if temp.right: 35 | queue.append(temp.right) 36 | print() 37 | 38 | 39 | 40 | 41 | def getlevelstr(node): 42 | """ 43 | 层次遍历出二叉树的序列,返回一个字符串来代替 44 | :param node: 45 | :return: 46 | """ 47 | result = "" 48 | queue = [node] 49 | while queue: 50 | temp = queue.pop(0) 51 | result += str(temp.data) 52 | if temp.left: 53 | queue.append(temp.left) 54 | if temp.right: 55 | queue.append(temp.right) 56 | return result 57 | 58 | def getchildstr(tree1root, tree2, tree1lists = []): 59 | """ 60 | 判断tree2是否为tree1的子树,其实就是判断层次遍历得到的结果中.根节点相同的两棵小树的遍历结果是否一致。 61 | :param tree1: 62 | :param tree2: 63 | :return: 64 | """ 65 | # 查找tree1中节点和tree2根节点相等的节点。 66 | if tree1root is None: 67 | return 68 | else: 69 | current = tree1root 70 | if current.data == tree2.root.data: 71 | tree1lists.append(getlevelstr(current)) 72 | # 当前“根”不符合要求,也得继续往下走啊 73 | if current.left: 74 | getchildstr(current.left, tree2, tree1lists) 75 | if current.right: 76 | getchildstr(current.right, tree2, tree1lists) 77 | 78 | 79 | 80 | if __name__ == '__main__': 81 | tree1 = Tree(8) 82 | tree1.root.left = Node(8) 83 | tree1.root.right = Node(7) 84 | tree1.root.left.left = Node(9) 85 | tree1.root.left.right = Node(2) 86 | tree1.root.left.right.left = Node(4) 87 | tree1.root.left.right.right = Node(7) 88 | tree1.root.left.right.right.left = Node(9) 89 | tree2 = Tree(8) 90 | tree2.root.left = Node(9) 91 | tree2.root.right = Node(2) 92 | tree2.root.right.left = Node(4) 93 | tree2.root.right.right = Node(7) 94 | 95 | # tree1.levelscan() 96 | # tree1.root = tree1.root.left 97 | # tree1.levelscan() 98 | # tree2.levelscan() 99 | 100 | # print(getlevelstr(tree1.root)) 101 | 102 | tree1lists = [] 103 | getchildstr(tree1.root, tree2, tree1lists) 104 | print(tree1lists) 105 | tree2str = getlevelstr(tree2.root) 106 | # 针对小树,其实还有可能是大树中子树的一部分,所以按照字符串包含与否来判断即可 107 | flag = False 108 | for tree1str in tree1lists: 109 | if tree2str in tree1str: 110 | flag = True 111 | break 112 | if flag: 113 | print('true') 114 | else: 115 | print('false') 116 | 117 | 118 | -------------------------------------------------------------------------------- /datastructor2/前序中序求后序.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 二叉树中和为某一个值的路径.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 根据前序遍历序列,中序遍历序列重建一棵二叉树 9 | 10 | class Node(object): 11 | def __init__(self, data=None, left=None, right=None): 12 | self.data = data 13 | self.left = left 14 | self.right = right 15 | 16 | def rebuild(pre, center): 17 | if not pre: 18 | return 19 | cur = Node(pre[0]) 20 | index = center.index(pre[0]) 21 | cur.left = rebuild(pre[1:index + 1], center[:index]) 22 | cur.right = rebuild(pre[index + 1:], center[index + 1:]) 23 | return cur 24 | 25 | def deep(root): 26 | if not root: 27 | return 28 | deep(root.left) 29 | deep(root.right) 30 | print (root.data) -------------------------------------------------------------------------------- /datastructor2/包含min函数得栈.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 包含min函数得栈.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 一个栈,实现min函数,并且min,pop,push操作的时间复杂度都得为O(1)。 9 | 10 | class Stack(object): 11 | """ 12 | 定义一个辅助栈,每次push数据的时候在辅助栈中只是添加最小的元素。 13 | """ 14 | def __init__(self): 15 | self.main = [] 16 | self.helper = [] 17 | 18 | def push(self, data): 19 | if self.main ==[]: 20 | self.main.append(data) 21 | self.helper.append(data) 22 | else: 23 | temp = self.main[-1] 24 | if temp <= data: 25 | self.helper.append(temp) 26 | else: 27 | self.helper.append(data) 28 | self.main.append(data) 29 | 30 | def pop(self): 31 | if self.main == []: 32 | print('栈空了,再也弹不出数据了呢!') 33 | else: 34 | self.helper.pop(len(self.helper)-1) 35 | return self.main.pop(len(self.main)-1) 36 | 37 | def min(self): 38 | """ 39 | 求得目前栈中的最小元素的值。 40 | :return: 41 | """ 42 | return self.helper[-1] 43 | 44 | 45 | if __name__ == '__main__': 46 | # 对入栈出栈进行测试! 47 | stack = Stack() 48 | stack.push(3) 49 | stack.push(5) 50 | stack.push(7) 51 | stack.push(1) 52 | print(stack.main) 53 | print(stack.helper) 54 | print(stack.pop()) 55 | print(stack.main) 56 | print(stack.helper) 57 | print(stack.pop()) 58 | print(stack.main) 59 | print(stack.helper) 60 | print(stack.pop()) 61 | print(stack.main) 62 | print(stack.helper) 63 | print(stack.pop()) 64 | print(stack.main) 65 | print(stack.helper) 66 | -------------------------------------------------------------------------------- /datastructor2/合并两个有序链表.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 合并两个有序链表.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 合并两个有序的链表。 9 | class Node(object): 10 | def __init__(self, data=None, next=None): 11 | self.data = data 12 | self.next = next 13 | 14 | 15 | class Chian(object): 16 | def __init__(self): 17 | self.head = None 18 | 19 | def addNode(self, data): 20 | if self.head is None: 21 | self.head = Node(data=data, next=None) 22 | else: 23 | cursor = self.head 24 | while cursor.next: 25 | cursor = cursor.next 26 | temp = Node(data=data, next=None) 27 | cursor.next = temp 28 | 29 | def printself(self): 30 | if self.head: 31 | cursor = self.head 32 | while cursor: 33 | print(cursor.data, end='\t') 34 | cursor = cursor.next 35 | print() 36 | 37 | def size(self): 38 | count = 0 39 | if self.head is None: 40 | return count 41 | else: 42 | cursor = self.head 43 | while cursor: 44 | cursor = cursor.next 45 | count += 1 46 | return count 47 | 48 | 49 | def merge(chain1, chain2): 50 | """ 51 | 合并两个有序的单链表 52 | :param chain1: 53 | :param chain2: 54 | :return: 55 | """ 56 | first = chain1.head 57 | second = chain2.head 58 | chain = Chian() 59 | while first and second: 60 | if first.data == second.data: 61 | chain.addNode(first.data) 62 | first = first.next 63 | if first.data < second.data: 64 | chain.addNode(first.data) 65 | first = first.next 66 | else: 67 | chain.addNode(second.data) 68 | second = second.next 69 | while first is not None: 70 | chain.addNode(first.data) 71 | first = first.next 72 | while second is not None: 73 | chain.addNode(second.data) 74 | second = second.next 75 | return chain 76 | 77 | 78 | def printchain(head): 79 | if head is None: 80 | return 81 | else: 82 | cursor = head 83 | while cursor: 84 | print(cursor.data, end='\t') 85 | cursor = cursor.next 86 | print() 87 | 88 | if __name__ == '__main__': 89 | chain1 = Chian() 90 | chain1.addNode(1) 91 | chain1.addNode(3) 92 | chain1.addNode(5) 93 | chain1.addNode(7) 94 | chain1.addNode(9) 95 | chain1.addNode(17) 96 | chain1.addNode(18) 97 | chain1.addNode(19) 98 | chain2 = Chian() 99 | chain2.addNode(1) 100 | chain2.addNode(5) 101 | chain2.addNode(6) 102 | chain2.addNode(8) 103 | chain2.addNode(10) 104 | chain1.printself() 105 | chain2.printself() 106 | print('开始合并!') 107 | chain = merge(chain1, chain2) 108 | chain.printself() 109 | -------------------------------------------------------------------------------- /datastructor2/堆和堆排序.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 堆和堆排序.py 5 | # @Time: 2017/4/18 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 堆和堆排序实现。 9 | 10 | class MaxHeap(object): 11 | """ 12 | 创建一个大顶堆。用数组(列表)作为存储容器来存储数据。 13 | """ 14 | def __init__(self, size): 15 | self.heap = [] 16 | # 先对容器进行初始化 17 | for index in range(size): 18 | self.heap.append(0) 19 | self.MAXSIZE = size 20 | self.currsize = 0 21 | 22 | def insert(self, data): 23 | """ 24 | 插入元素的时候,先放到这个“完全二叉树”的末尾位置。然后让它和其父节点进行大小比较: 25 | 如果父节点大, 那么说明这个插入值放到这个位置是合理的; 26 | 如果当前节点的值更大,说明需要和父节点交换位置,然后进行新一轮的比较。 27 | 直到比较到了根节点,(根节点没有父节点了,此时循环比较的过程就可以结束了)。 28 | 当然了,如果当前堆还没有数据,那么直接把这个数据放到根节点的位置即可。 29 | :param data: 30 | :return: 31 | """ 32 | if self.currsize == self.MAXSIZE: 33 | print('插入失败,堆空间已满!') 34 | return False 35 | else: 36 | self.currsize += 1 37 | flag = self.currsize -1 38 | while flag > 0: 39 | parent = int((flag-1)/2) 40 | if self.heap[parent] > data : 41 | self.heap[flag] = data 42 | return True 43 | else: 44 | self.heap[flag] = self.heap[parent] 45 | flag = parent 46 | # 如果循环条件没满足,说明现在堆是空的,直接在根节点上赋值即可。 47 | self.heap[0] = data 48 | return True 49 | 50 | def siftdown(self, flag): 51 | """ 52 | 给定一个位置,对堆的结构进行调整。 53 | :param flag: 54 | :return: 55 | """ 56 | want = flag 57 | x = self.heap[flag] 58 | 59 | while want < self.currsize: 60 | lchild = 2*want +1 61 | rchild = 2*want +2 62 | if lchild > self.currsize: 63 | # 没有孩子节点,直接放即可 64 | self.heap[want] = x 65 | else: 66 | # 有左右孩子节点, 找到待换位置 67 | if lchild < self.currsize: 68 | maxchildposition = lchild if self.heap[lchild] > self.heap[rchild] else rchild 69 | else: 70 | # 至少可以有左孩子 71 | maxchildposition = lchild 72 | # 开始调换数据 73 | if self.heap[maxchildposition] < x: 74 | self.heap[want] = x 75 | return 76 | else: 77 | self.heap[want] = self.heap[maxchildposition] 78 | want = maxchildposition 79 | 80 | def deletetop(self): 81 | if self.currsize < 0: 82 | print('堆空,无法再进行数据删除了!') 83 | return 84 | else: 85 | target = self.heap[0] 86 | substitute = self.heap[self.currsize-1] 87 | self.currsize -= 1 88 | self.heap[0] = substitute 89 | self.siftdown(0) 90 | return target 91 | 92 | if __name__ == '__main__': 93 | maxheap = MaxHeap(7) 94 | for index in range(1, 8): 95 | maxheap.insert(index) 96 | # 测试弹出数据 97 | for index in range(1, 8): 98 | print(maxheap.deletetop()) 99 | -------------------------------------------------------------------------------- /datastructor2/快速排序.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | def sort(ls, left, right): 4 | pivot = ls[left] 5 | while left < right: 6 | while left < right and ls[right] >= pivot: 7 | right -= 1 8 | ls[left] = ls[right] 9 | while left < right and ls[left] <= pivot: 10 | left += 1 11 | ls[right] = ls[left] 12 | ls[left] = pivot 13 | return left 14 | 15 | def quicksort(ls,left, right): 16 | if left < right : 17 | pivot = sort(ls, left, right) 18 | quicksort(ls, left, pivot-1) 19 | quicksort(ls, pivot+1, right) 20 | 21 | def beautify_version(ls): 22 | if ls == []: 23 | return [] 24 | else: 25 | temp = ls[0] 26 | left = beautify_version([x for x in ls[1:] if x < ls[0]]) 27 | right = beautify_version([x for x in ls[1:] if x >= ls[0]]) 28 | return left + [temp] + right 29 | 30 | 31 | def qiucksortinoneline(ls): 32 | """ 33 | 一行代码实现的快速排序算法 34 | """ 35 | return [] if ls == [] else qiucksortinoneline([x for x in ls[1:] if x < ls[0]]) + [ls[0]] + qiucksortinoneline([x for x in ls[1:] if x >= ls[0]]) 36 | 37 | 38 | def quick(ls): 39 | return [] if ls == [] else quick([x for x in ls[1:] if x < ls[0]]) + [ls[0]]+quick([x for x in ls[1:] if x>=ls[0]]) 40 | 41 | if __name__ == '__main__': 42 | ls = [3,5,7,9,1,4,6,2,8] 43 | print('排序前: ', ls) 44 | # quicksort(ls, 0, len(ls)-1) 45 | # ls = qiucksortinoneline(ls) 46 | # qiucksortinoneline(ls) 47 | # ls = beautify_version(ls) 48 | ls = quick(ls) 49 | print('排序后: ', ls) 50 | -------------------------------------------------------------------------------- /datastructor2/把数组排成最小的数.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 把数组排成最小的数.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 把数组排成最小的数 9 | 10 | def fulllist(ls, result=[], position=0): 11 | if position == len(ls)-1: 12 | result.append(''.join(ls)) 13 | else: 14 | for index in range(len(ls)): 15 | ls[index], ls[position] = ls[position], ls[index] 16 | fulllist(ls, result, position+1) 17 | ls[position], ls[index] = ls[index], ls[position] 18 | 19 | 20 | def method1(ls): 21 | """ 22 | 借助“全排列”组装成数,再求最小的那个 23 | :param ls: 24 | :return: 25 | """ 26 | resultlist = [] 27 | fulllist(ls, resultlist, 0) 28 | return min([int(item) for item in resultlist]) 29 | 30 | if __name__ == '__main__': 31 | # ls = ['321', '32', '3'] 32 | ls = ['12', '1'] 33 | result = method1(ls) 34 | print(result) -------------------------------------------------------------------------------- /datastructor2/数组中出现次数最多的那个元素的值.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 数组中出现次数最多的那个元素的值.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 数组中出现次数最多的那个元素的值。如[1,2,3,4,5,6,2,2,2,2,27,8]结果为2 9 | 10 | def run(ls): 11 | """ 12 | 基于桶排序原理,这里使用字典代替,统计每个元素出现的次数。但是天生对负数无效哦。切记!!! 13 | :param ls: 14 | :return: 15 | """ 16 | dic = dict() 17 | for index in range(max(ls)): 18 | dic[str(index)] = 0 19 | # 开始统计 20 | for item in ls: 21 | if str(item) in dic.keys(): 22 | dic[str(item)] += 1 23 | # 返回出现次数最多的那个元素的值 24 | temp = -1 25 | target = 0 26 | for key, value in dic.items(): 27 | if temp <=value: 28 | target = key 29 | temp = value 30 | return target 31 | 32 | if __name__ == '__main__': 33 | ls = [1,2,3,4,5,6,2,2,2,2,27,7,7,7,7,7,7,7,78,9] 34 | result = run(ls) 35 | print(result) -------------------------------------------------------------------------------- /datastructor2/栈的压入弹出序列合法性判断.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 栈的压入弹出序列合法性判断.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 栈的压入弹出序列合法性判断。如入栈:12345.出栈可以使45321,但是不能是43512 9 | 10 | # TODO: 待做。 11 | -------------------------------------------------------------------------------- /datastructor2/求1+2+到N.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 求1+2+到N.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 要求不使用乘除法,for,while,if,else,switch,case等关键字和三目运算实现这个和的运算。 9 | 10 | def getsum(n): 11 | result = 0 12 | if n >0: 13 | result=getsum(n-1)+n 14 | return result 15 | 16 | if __name__ == '__main__': 17 | result = getsum(5) 18 | print(result) 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /datastructor2/求一可棵二叉树的镜像.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 求一可棵二叉树的镜像.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 求一可棵二叉树的镜像 9 | class Node(object): 10 | def __init__(self, data=None, left=None, right=None): 11 | self.data = data 12 | self.left = left 13 | self.right = right 14 | 15 | class Tree(object): 16 | def __init__(self, data=None): 17 | self.root = Node(data, None, None) 18 | 19 | def levelscan(self): 20 | """ 21 | 层次遍历二叉树。也即是广度优先遍历二叉树。 22 | :return: 23 | """ 24 | if self.root is None: 25 | return 26 | else: 27 | queue = [self.root] 28 | while queue: 29 | temp = queue.pop(0) 30 | print(temp.data, end='\t') 31 | if temp.left: 32 | queue.append(temp.left) 33 | if temp.right: 34 | queue.append(temp.right) 35 | print() 36 | 37 | 38 | def mirror(root): 39 | """ 40 | 求一棵二叉树的镜像树 41 | :return: 42 | """ 43 | if root is None: 44 | return 45 | else: 46 | root.left, root.right = root.right, root.left 47 | mirror(root.left) 48 | mirror(root.right) 49 | 50 | 51 | if __name__ == '__main__': 52 | tree = Tree(1) 53 | tree.root.left = Node(2) 54 | tree.root.right = Node(3) 55 | tree.root.left.left = Node(4) 56 | tree.root.left.right = Node(5) 57 | tree.root.right.left = Node(6) 58 | tree.root.right.right = Node(7) 59 | print('二叉树逆转之前:') 60 | tree.levelscan() 61 | # 开始镜像逆转 62 | mirror(tree.root) 63 | print('二叉树逆转之后:') 64 | tree.levelscan() -------------------------------------------------------------------------------- /datastructor2/求两个链表的第一个公共节点.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 求两个链表的第一个公共节点.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 求两个链表的第一个公共节点。暴力法O(mn),所以空间换时间用栈特性,出栈的时候最后一个不等的节点就是公共节点了。 9 | class Node(object): 10 | def __init__(self, data=None, next=None): 11 | self.data = data 12 | self.next = next 13 | 14 | 15 | class Chian(object): 16 | def __init__(self): 17 | self.head = None 18 | 19 | def addNode(self, data): 20 | if self.head is None: 21 | self.head = Node(data=data, next=None) 22 | else: 23 | cursor = self.head 24 | while cursor.next: 25 | cursor = cursor.next 26 | temp = Node(data=data, next=None) 27 | cursor.next = temp 28 | 29 | def printself(self): 30 | if self.head: 31 | cursor = self.head 32 | while cursor: 33 | print(cursor.data, end='\t') 34 | cursor = cursor.next 35 | print() 36 | 37 | def size(self): 38 | count = 0 39 | if self.head is None: 40 | return count 41 | else: 42 | cursor = self.head 43 | while cursor: 44 | cursor = cursor.next 45 | count += 1 46 | return count 47 | 48 | def sharedNode(chain1, chain2): 49 | s1 = [] 50 | cursor = chain1.head 51 | while cursor: 52 | s1.append(cursor.data) 53 | cursor = cursor.next 54 | s2 = [] 55 | cursor = chain2.head 56 | while cursor: 57 | s2.append(cursor.data) 58 | cursor = cursor.next 59 | # 出栈,找最后一个不相等的节点值 60 | while s1 and s2: 61 | temp1, temp2 = s1.pop(), s2.pop() 62 | if temp1 == temp2: 63 | target = temp1 64 | else: 65 | return target 66 | 67 | def withoutStack(chian1, chian2): 68 | size1 = chian1.size() 69 | size2 = chian2.size() 70 | # 默认chian1更长 71 | first = chian1.head 72 | second = chian2.head 73 | index = 0 74 | while index result: 24 | result = currsum 25 | 26 | return result 27 | 28 | if __name__ == '__main__': 29 | ls = [1, -2, 3, 10, -4, 7, 2, -5] 30 | result = run(ls) 31 | print(result) 32 | -------------------------------------------------------------------------------- /datastructor2/链表中倒数第K个数.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 链表中倒数第K个数.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 求出单链表中的倒数第K个节点的元素的值 9 | 10 | class Node(object): 11 | def __init__(self, data=None, next=None): 12 | self.data = data 13 | self.next = next 14 | 15 | 16 | class Chian(object): 17 | def __init__(self): 18 | self.head = None 19 | 20 | def addNode(self, data): 21 | if self.head is None: 22 | self.head = Node(data=data, next=None) 23 | else: 24 | cursor = self.head 25 | while cursor.next: 26 | cursor = cursor.next 27 | temp = Node(data=data, next=None) 28 | cursor.next = temp 29 | 30 | def printself(self): 31 | if self.head: 32 | cursor = self.head 33 | while cursor: 34 | print(cursor.data) 35 | cursor = cursor.next 36 | 37 | def size(self): 38 | count = 0 39 | if self.head is None: 40 | return count 41 | else: 42 | cursor = self.head 43 | while cursor: 44 | cursor = cursor.next 45 | count += 1 46 | return count 47 | 48 | def indexOfReverseK(self, k): 49 | """ 50 | 咱们默认负数没有意义,虽然对于负数的情况可以使用正序链表来解决。 51 | :param k: 52 | :return: 53 | """ 54 | if self.head is None: 55 | return 56 | if self.head and k <= 0: 57 | # 因为倒数第0个元素没有意义,所以直接返回即可。 58 | return None 59 | if self.size() < k: 60 | print('链表没那么长,老哥!') 61 | return 62 | 63 | if self.size() == k: 64 | return self.head.data 65 | else: 66 | # 有两个思路一个是双指针方式,另一个采用逆序链表再正序查找第k个元素,接下来分别实现之。 67 | # return self.doublepointer(k) 68 | return self.reverseway(k) 69 | 70 | def doublepointer(self, k): 71 | first, second = self.head, self.head 72 | for index in range(k): 73 | first = first.next 74 | while first: 75 | first = first.next 76 | second = second.next 77 | return second.data 78 | 79 | 80 | def reverse(self): 81 | if self.head is None: 82 | return 83 | if self.size() == 1: 84 | return self.head 85 | else: 86 | cursor = self.head 87 | pre = None 88 | post = None 89 | while cursor: 90 | post = cursor.next 91 | cursor.next = pre 92 | pre = cursor 93 | cursor = post 94 | self.head = pre 95 | 96 | 97 | def reverseway(self, k): 98 | # 先把原来的链表逆序,然后正序查找到第K个元素,最后别忘了将链表逆序回来。 99 | self.reverse() 100 | counter = 1 101 | cursor = self.head 102 | result = None 103 | while cursor: 104 | if counter == k: 105 | result = cursor.data 106 | break 107 | counter += 1 108 | cursor = cursor.next 109 | self.reverse() 110 | return result 111 | 112 | 113 | 114 | 115 | 116 | if __name__ == '__main__': 117 | chain = Chian() 118 | chain.addNode(0) 119 | chain.addNode(1) 120 | chain.addNode(2) 121 | chain.addNode(3) 122 | chain.printself() 123 | # chain.reverse() 124 | # chain.printself() 125 | print("链表的大小:", chain.size()) 126 | thek = chain.indexOfReverseK(4) 127 | print("倒数第K个元素的值为:", thek) 128 | doublepointerwayk = chain.indexOfReverseK(0) 129 | print("采用双指针的形式实现的倒数第K个元素的值为:", doublepointerwayk) 130 | reversewayk = chain.indexOfReverseK(3) 131 | print("采用逆序算法实现的倒数第K个元素的值为: ", reversewayk) 132 | -------------------------------------------------------------------------------- /datastructor2/顺时针打印矩阵.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 顺时针打印矩阵.py 5 | # @Time: 2017/4/16 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 使用顺时针的方向打印一个矩阵。 9 | 10 | # TODO: 还是有点问题,对于奇数矩阵还是会多打印出重复数据。对于偶数矩阵可行。 11 | def transfer(ls): 12 | """ 13 | 顺时针打印一个矩阵。需要考虑的是方阵和普通矩阵的情况。 14 | :param ls: 15 | :return: 16 | """ 17 | row = len(ls) 18 | col = len(ls[0]) 19 | # 对于奇数矩阵循环控制会有些困难!!!!!!!!!!尴尬。 20 | for outter in range(int((row)/2)): 21 | # 打印上面一层 22 | for x in range(outter, col-outter*2): 23 | print(ls[outter][x], end='\t') 24 | # 打印右边一列 25 | for y in range(1,row-outter*2): 26 | print(ls[y][col-1-outter], end='\t') 27 | # 打印下面一行 28 | for x in range(1,row-outter): 29 | print(ls[row-1-outter][col-1-x], end='\t') 30 | # 打印左边一列 31 | for y in range(1+outter,row- outter-1): 32 | print(ls[col-1-y][outter], end='\t') 33 | # 开始准备下一轮 34 | print() 35 | 36 | 37 | if __name__ == '__main__': 38 | 39 | # ls = [ 40 | # [1,2], 41 | # [3,4] 42 | # ] 43 | 44 | ls = [ 45 | [1,2,3,4], 46 | [5,6,7,8], 47 | [9,10,11,12], 48 | [13,14,15,16] 49 | ] 50 | # ls = [ 51 | # [1,2,3,4,5], 52 | # [6,7,8,9,10], 53 | # [11,12,13,14,15], 54 | # [16,17,18,19,20], 55 | # [21,22,23,24,25] 56 | # ] 57 | transfer(ls) -------------------------------------------------------------------------------- /jingdong/1.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 1.py 5 | # @Time: 2017/4/7 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 京东笔试第一题:求两个二进制数异或运算后的十进制的结果 9 | 10 | a = '1100' 11 | b = '0100' 12 | 13 | def getlist(n, a, b): 14 | result = [] 15 | for index in range(n): 16 | if a[index] != b[index]: 17 | result.append('1') 18 | else: 19 | result.append('0') 20 | return result 21 | 22 | 23 | 24 | def compute(s): 25 | s.reverse() 26 | # print(s) 27 | sum = 0 28 | for index in range(len(s)): 29 | if s[index]!='0': 30 | sum += int(pow(2, int(index))) 31 | return sum 32 | 33 | n = int(input()) 34 | a = input() 35 | b = input() 36 | 37 | result = getlist(n, a, b) 38 | result = compute(result) 39 | print(result) -------------------------------------------------------------------------------- /jingdong/2.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 2.py 5 | # @Time: 2017/4/7 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 京东笔试第二题,没思路。(⊙﹏⊙)b 9 | 10 | n = int(input()) 11 | k = int(input()) 12 | 13 | temp = n%3 14 | 15 | if k==1: 16 | if temp==0: 17 | print(int(n/3)*2) 18 | elif temp ==1: 19 | print(int((n+2)/3)*2) 20 | else: 21 | print(int((n + 1) / 3) * 2) 22 | elif k ==2: 23 | if temp == 0: 24 | print(n-int(n / 3 * 2)+1) 25 | elif temp ==1: 26 | print(n-int((n+2)/3)*2) 27 | else: 28 | print(n - int((n + 1) / 3) * 2) -------------------------------------------------------------------------------- /jingdong/temp-2.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: temp-2.py 5 | # @Time: 2017/4/7 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 临时测试文件,测完即可删除 9 | 10 | nk = input().split(' ') 11 | n, k = int(nk[0]), int(nk[-1]) 12 | 13 | if n == 2: 14 | if k == 1: 15 | print 16 | 1 17 | elif k == 2: 18 | print 19 | 0 20 | else: 21 | print 22 | 0 23 | elif n == 3: 24 | if k == 1: 25 | print 26 | 2 27 | elif k == 2: 28 | print 29 | 1 30 | else: 31 | print 32 | 0 33 | elif n == 4: 34 | if k == 1: 35 | print 36 | 3 37 | elif k == 2: 38 | print 39 | 1 40 | else: 41 | print 42 | 0 43 | elif n == 5: 44 | if k == 1: 45 | print 46 | 3 47 | elif k == 2 or k == 3 or k == 4: 48 | print 49 | 1 50 | else: 51 | print 52 | 0 53 | elif n == 6: 54 | if k == 1: 55 | print 56 | 4 57 | elif k == 2: 58 | print 59 | 2 60 | elif k == 3: 61 | print 62 | 1 63 | else: 64 | print 65 | 0 66 | elif n == 7: 67 | if k == 1: 68 | print 69 | 5 70 | elif k == 2: 71 | print 72 | 2 73 | elif k == 3: 74 | print 75 | 2 76 | elif k == 4 or k == 5: 77 | print 78 | 1 79 | else: 80 | print 81 | 0 82 | -------------------------------------------------------------------------------- /mkreadme.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: mkreadme.py 5 | # @Time: 2017/4/14 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 将当前目录中所有的文件生成markdown文件特有的链接形式 9 | 10 | import os 11 | import re 12 | 13 | def pathwalk(path='.', result=[]): 14 | dirlist = os.listdir(path=path) 15 | 16 | for item in dirlist: 17 | child = os.path.join(path, item) 18 | if os.path.isfile(child): 19 | result.append(child) 20 | # print(child) 21 | else: 22 | pathwalk(child, result) 23 | 24 | 25 | def getdescription(list): 26 | return "".join([str(item) for item in list if "@Description:" in str(item)]) 27 | 28 | def generate(files=[], outputpath='./readme.md', site='your repository link'): 29 | info = {} 30 | for file in files: 31 | if 'readme.' in str(file) or '.git\\' in str(file): 32 | continue 33 | with open(file, 'r', encoding='utf8') as f: 34 | temp = getdescription(f.readlines()) 35 | temp = temp[15:] 36 | info[str(file)] = temp 37 | f.close() 38 | # print(len(info), info) 39 | info = {k:v for k,v in info.items() if v!='' and 'readme.' not in str(k) and '.git\\' not in str(k)} 40 | print(len(info), info) 41 | 42 | # 生成Markdown文件 43 | with open(outputpath, 'a', encoding='utf8') as f: 44 | # f.write('标题部分\n---') 45 | for key, value in info.items(): 46 | key = site+changesepqrter(key) 47 | temp = " - [{}]({})\n\n".format(value, key) 48 | f.write(temp) 49 | f.close() 50 | print('文件已生成!') 51 | 52 | 53 | def changesepqrter(path): 54 | path = path[2:] 55 | # 第三个参数默认为全部替换,如果设置了个数,则按照个数来从左至右替换。 56 | path = str(path).replace('\\', '/') 57 | return path 58 | 59 | if __name__ == '__main__': 60 | path = '.' 61 | result = [] 62 | site = 'https://github.com/guoruibiao/sword-to-offer/blob/master/' 63 | pathwalk(path, result) 64 | print(result) 65 | generate(result, site=site) 66 | 67 | -------------------------------------------------------------------------------- /xiecheng/1.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | 3 | # @Author: 郭 璞 4 | # @File: 1.py 5 | # @Time: 2017/4/11 6 | # @Contact: 1064319632@qq.com 7 | # @blog: http://blog.csdn.net/marksinoberg 8 | # @Description: 携程笔试第一题题解思路 9 | 10 | #include 11 | #include 12 | # using namespace std; 13 | # //把自然数N分解成若干个互不相同的正整数,使乘积最大; 14 | # /** 15 | # 题意挺晦涩的,就是说要维持这个会议召开需要满足几个条件,而要会议召开最久需要这个条件尽可能久的维持 16 | # 接着就需要了将整数N分解任意个不同的整数,使这些整数的乘积最大 17 | # 将N分解为N=a1+a2+a3+..+ak 18 | # 可以归纳出这么一些规律 19 | # 1.a1>1 如果a1=1,那么将a1加到ak上,必然使得到的这个乘积大于原来的乘积 20 | # 2.2>=a[i+1]-a[i]>=1,因为如果出现>2,可以将a[i+1],a[i]改为a[i+1]-1,a[i]+1,使得到的乘积更大 21 | # 3.最多只有一个i,使得a[i+1]-a[i]=2 22 | # 反证法,假设i=4,那么将a1,a2替换成2,a1-1,a2-1将使得乘积更大 25 | # 5.如果a1=3,并且存在一个i使得a[i+1]-a[i]=2,那么i一定为t-1 26 | # 做法就是求出以2起始的最大连续自然数序列之和sum,使得sum的值不超过输入数n, 27 | # 然后分情况讨论: 28 | # 设此最大序列为2、3、……、w,则: 29 | # 1。若剩余值(n-sum)等于w,则最后输出序列为:3、4、……、w、w+2,即将原最大序列每项加1,再将最后剩余的一个1加到最后一项上。 30 | # 2。若剩余值(n-sum)小于w,则从序列的最大项i开始,从大到小依次将每项加1,直到剩余值用完。 31 | # */ 32 | # int a[1000]; 33 | # int n; 34 | # int main() 35 | # { 36 | # while(scanf("%d",&n)==1) 37 | # { 38 | # int sum=0,l=0,left; 39 | # for(int i=2;i<=n;i++) 40 | # { 41 | # a[l++]=i; 42 | # sum+=i; 43 | # if(sum>n) 44 | # { 45 | # sum-=i,l--,left=n-sum; 46 | # break; 47 | # } 48 | # } 49 | # for(int i=l-1;left;left--) 50 | # { 51 | # a[i]++; 52 | # i--; 53 | # if(i<0) i=l-1; 54 | # } 55 | # for(int i=0;i n: 73 | last = path.pop() 74 | path.append(path.pop() + n - (cursum - last)) 75 | break 76 | path.append(index) 77 | cursum += index 78 | return mutl(path) 79 | 80 | def my(n): 81 | total = [] 82 | maxvalue = 0 83 | for step in range(int(n/2)): 84 | item = compute(n, step) 85 | total.append(item) 86 | maxvalue = max(total) 87 | return maxvalue 88 | 89 | 90 | 91 | n = input() 92 | result= my(n) 93 | print(result) 94 | 95 | --------------------------------------------------------------------------------