diff --git a/QuickSort.py b/QuickSort.py index 59b0972..de9eb3a 100644 --- a/QuickSort.py +++ b/QuickSort.py @@ -1,46 +1,38 @@ -# coding: utf-8 - def quickSort(alist): - quickSortHelper(alist, 0, len(alist)-1) - + quickSortHelper(alist, 0, len(alist) - 1) + def quickSortHelper(alist, first, last): if first < last: splitPoint = partition(alist, first, last) - + quickSortHelper(alist, first, splitPoint-1) quickSortHelper(alist, splitPoint+1, last) - + + def partition(alist, first, last): - pivotvlue = alist[first] - - leftmark = first+1 + base = alist[first] + + + + leftmark = first rightmark = last - done = False - - while not done: - while leftmark <= rightmark and alist[leftmark] <= pivotvlue: # bugfix: 先比较index, 不然数组会越界 + + while leftmark < rightmark: # 要求左指针必须小于等于右指针,之所以没有等号是因为,在最后一次指针移动的时候就会取等, + # 不满足小于条件的时候其实已经取等了 + if alist[leftmark] <= base: leftmark += 1 - while rightmark >= leftmark and alist[rightmark] >= pivotvlue: + if alist[rightmark] >= base: rightmark -= 1 - - if leftmark > rightmark: - done = True - else: + + else: # 当左右指针都停止的时候,交换左右指针所对应的值 alist[leftmark], alist[rightmark] = alist[rightmark], alist[leftmark] + + # 当左指针和右指针重合的时候,交换右指针对应的值和base对应的值 alist[rightmark], alist[first] = alist[first], alist[rightmark] - return rightmark - + + return rightmark # rightmark是作为递归排序的标记,所以返回。最后输出alist就是直接排序排好的 + + alist = [54,26,93,17,77,31,44,55,20] -alist2 = [1] -quickSort(alist2) -print(alist2) - - -if __name__ == "__main__": - test_data = [3,2,111,3,-1,0,0,1,0,2,4] - - res_stable = sorted(test_data) - quickSort(test_data) - print(test_data) - print(res_stable) - assert all(map(lambda x: x[0] == x[1], zip(res_stable, test_data))) \ No newline at end of file +quickSort(alist) +print(alist) \ No newline at end of file diff --git a/README.md b/README.md index f0cafe6..0edb458 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ [队列](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Queue.py) -[快排](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/QuickSort.py) +[快速排序](https://github.com/Einstellung/AlgorithmsByPython/blob/master/QuickSort.py) [基数排序](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/RadixSort.py) @@ -67,19 +67,23 @@ [面试题2:实现Singleton模式](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/Singleton.py) -[面试题3:二维数组中的查找](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E6%9F%A5%E6%89%BE.py):对于在一个每一行从左到右依次递增,每一列从上到下依次递增的二维数组查找一个元素,可以选择从数组左上角开始查找array[i]\[j],如果目标元素大于array[i]\[j],i+=1,如果元素小于array[i]\[j],j-=1,依次循环直至找到这个数。 +[面试题4:二维数组中的查找](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84%E6%9F%A5%E6%89%BE.py):对于在一个每一行从左到右依次递增,每一列从上到下依次递增的二维数组查找一个元素,可以选择从数组左上角开始查找array[i]\[j],如果目标元素大于array[i]\[j],i+=1,如果元素小于array[i]\[j],j-=1,依次循环直至找到这个数。 -[面试题4:替换空格](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E6%9B%BF%E6%8D%A2%E7%A9%BA%E6%A0%BC.py):如果直接每次遇到空格添加'%20',那么空格后面的数字就需要频繁向后移动。遇到这种移动问题,我们可以尝试先给出最终需要的长度,然后从后向前扫描,同时给定两个指针来保证定位。**逆向思维** +[面试题5:替换空格](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E6%9B%BF%E6%8D%A2%E7%A9%BA%E6%A0%BC.py):如果直接每次遇到空格添加'%20',那么空格后面的数字就需要频繁向后移动。遇到这种移动问题,我们可以尝试先给出最终需要的长度,然后从后向前扫描,同时给定两个指针来保证定位。**逆向思维** -[面试题5:从头到尾打印链表](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E5%8F%8D%E5%90%91%E6%89%93%E5%8D%B0%E9%93%BE%E8%A1%A8.py):从头到尾遍历链表,并用一个栈存储每个结点的值,之后出栈输出值即可。 +[面试题6:从头到尾打印链表](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E5%8F%8D%E5%90%91%E6%89%93%E5%8D%B0%E9%93%BE%E8%A1%A8.py):从头到尾遍历链表,并用一个栈存储每个结点的值,之后出栈输出值即可。 -[面试题6:重建二叉树](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E9%87%8D%E5%BB%BA%E4%BA%8C%E5%8F%89%E6%A0%91.py):利用二叉树前序遍历和中序遍历的特性。前序遍历的第一个值一定为根节点,对应于中序遍历中间的一个点。在中序遍历序列中,这个点左侧的均为根的左子树,这个点右侧的均为根的右子树。这时可以利用递归,分别取前序遍历[1:i+1]和中序遍历的[:i]对应与左子树继续上一个过程,取前序遍历[i+1:]和中序遍历[i+1]对应于右子树继续上一个过程,最终得以重建二叉树。 +[面试题7:重建二叉树](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E9%87%8D%E5%BB%BA%E4%BA%8C%E5%8F%89%E6%A0%91.py):利用二叉树前序遍历和中序遍历的特性。前序遍历的第一个值一定为根节点,对应于中序遍历中间的一个点。在中序遍历序列中,这个点左侧的均为根的左子树,这个点右侧的均为根的右子树。这时可以利用递归,分别取前序遍历[1:i+1]和中序遍历的[:i]对应与左子树继续上一个过程,取前序遍历[i+1:]和中序遍历[i+1]对应于右子树继续上一个过程,最终得以重建二叉树。 -[面试题7:用两个栈实现队列](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E7%94%A8%E4%B8%A4%E4%B8%AA%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.py):需要两个栈Stack1和Stack2,push的时候直接push进Stack1。pop需要判断Stack1和Stack2中元素的情况,Stack1空的话,直接从Stack2 pop,Stack1不空的话,把Stack1的元素push进入Stack2,然后pop Stack2的值。[推广:用两个队列实现栈](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E7%94%A8%E4%B8%A4%E4%B8%AA%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.py) +[面试题8:二叉树的下一个结点](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E4%B8%8B%E4%B8%80%E4%B8%AA%E7%BB%93%E7%82%B9.py):三种情况:当前节点有右子树的话,当前节点的下一个结点是右子树中的最左子节点;当前节点无右子树但是是父节点的左子节点,下一个节点是当前结点的父节点;当前节点无右子树而且是父节点的右子节点,则一直向上遍历,直到找到最靠近的一个祖先节点pNode,pNode是其父节点的左子节点,那么输入节点的下一个结点就是pNode的父节点。 + +[面试题9:用两个栈实现队列](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E7%94%A8%E4%B8%A4%E4%B8%AA%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.py):需要两个栈Stack1和Stack2,push的时候直接push进Stack1。pop需要判断Stack1和Stack2中元素的情况,Stack1空的话,直接从Stack2 pop,Stack1不空的话,把Stack1的元素push进入Stack2,然后pop Stack2的值。[推广:用两个队列实现栈](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E7%94%A8%E4%B8%A4%E4%B8%AA%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.py) + +[面试题10:斐波那契数列](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97.py):如何不使用递归实现斐波那契数列,需要把前面两个数字存入在一个数组中。斐波那契数列的变形有很多,如[青蛙跳台阶](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E9%9D%92%E8%9B%99%E8%B7%B3%E5%8F%B0%E9%98%B6.py),一次跳一个或者两个;铺瓷砖问题。[**变态青蛙跳**](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E5%8F%98%E6%80%81%E9%9D%92%E8%9B%99%E8%B7%B3%E5%8F%B0%E9%98%B6.py),每次至少跳一个,至多跳n个,一共有f(n)=2n-1种跳法。考察数学建模的能力。以及[矩形覆盖问题](https://blog.csdn.net/Einstellung/article/details/90020345) + +[面试题11:旋转数组的最小数字](https://github.com/Einstellung/AlgorithmsByPython/blob/master/Target%20Offer/%E6%97%8B%E8%BD%AC%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%B0%8F%E6%95%B0%E5%AD%97.py):二分查找的变形,注意到旋转数组的首元素肯定不小于旋转数组的尾元素,设置中间点。如果中间点大于首元素,说明最小数字在后面一半,如果中间点小于尾元素,说明最小数字在前一半。依次循环。同时,当一次循环中首元素小于尾元素,说明最小值就是首元素。但是当首元素等于尾元素等于中间值,只能在这个区域顺序查找。 -[面试题8:旋转数组的最小数字](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E6%97%8B%E8%BD%AC%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%B0%8F%E6%95%B0%E5%AD%97.py):二分查找的变形,注意到旋转数组的首元素肯定不小于旋转数组的尾元素,设置中间点。如果中间点大于首元素,说明最小数字在后面一半,如果中间点小于尾元素,说明最小数字在前一半。依次循环。同时,当一次循环中首元素小于尾元素,说明最小值就是首元素。但是当首元素等于尾元素等于中间值,只能在这个区域顺序查找。 -[面试题9:斐波那契数列](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97.py):如何不使用递归实现斐波那契数列,需要把前面两个数字存入在一个数组中。斐波那契数列的变形有很多,如青蛙跳台阶,一次跳一个或者两个;铺瓷砖问题。**变态青蛙跳**,每次至少跳一个,至多跳n个,一共有f(n)=2n-1种跳法。考察数学建模的能力。 [面试题10:二进制中1的个数](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%B8%AD1%E7%9A%84%E4%B8%AA%E6%95%B0.py):注意到每个**非零**整数n和n-1进行按位与运算,整数n的二进制数中最右边的1就会变成0,那么二进制数中的1的个数就会减少一个,因此可以利用一个循环,使得 n = n&(n-1) ,计算经过几次运算减少到0,就是有几个1。注意:书中给了另外两种方法,分别是原始n左移一位和右移一位的方法,因为Python不会出现整数溢出的情况,这里就不再考虑着两种方法。扩展:判断一个数值是不是2得整数次方,如果是的话,这个数的二进制数中有且只有一个1,那么这个数n会有 n&(n-1) == 0。或者求两个整数m和n需要改变m二进制中的多少位才能得到n,可以先做 m^n 的异或运算,然后求这个数中有多少个1。 @@ -183,8 +187,6 @@ [面试题57:删除链表中重复的结点](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E5%88%A0%E9%99%A4%E9%93%BE%E8%A1%A8%E4%B8%AD%E9%87%8D%E5%A4%8D%E7%9A%84%E7%BB%93%E7%82%B9.py):我们需要设置一个指针preNode,preNode最开始为None,然后设置两个指针,pNode指向当前节点,pNext指向pNode下一个结点,⓵如果pNext不为空而且pNext的值等于pNode的值,那么就说明出现了重复数字的结点,就需要删除,然后从pNode开始遍历,如果结点值等于前面那个重复值,继续遍历。当遍历到None或者不同值结点的时候,这时候需要判断preNode结点,如果preNode结点为None,就说明我们刚才的重复结点是从整个链表的头结点开始重复的,就直接把pHead设置为当前结点,pNode也设置为当前结点。反之,如果preNode不为None,直接把preNode的下一个指针指向当前节点,pNode指向preNode即可;⓶如果pNext为空或者pNext的值不等于pNode的值,说明当前的这个pNode和后面的值不重复,直接令preNode = pNode,pNode指向下一个结点即可。 -[面试题58:二叉树的下一个结点](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E4%B8%8B%E4%B8%80%E4%B8%AA%E7%BB%93%E7%82%B9.py):三种情况:当前节点有右子树的话,当前节点的下一个结点是右子树中的最左子节点;当前节点无右子树但是是父节点的左子节点,下一个节点是当前结点的父节点;当前节点无右子树而且是父节点的右子节点,则一直向上遍历,直到找到最靠近的一个祖先节点pNode,pNode是其父节点的左子节点,那么输入节点的下一个结点就是pNode的父节点。 - [面试题59:对称的二叉树](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E5%AF%B9%E7%A7%B0%E7%9A%84%E4%BA%8C%E5%8F%89%E6%A0%91.py):分为递归和非递归的两种方式,思想是一样的。主要就是把叶子节点的None节点也加入到遍历当中。按照前序遍历二叉树,存入一个序列中。然后按照和前序遍历对应的先父节点,然后右子节点,最后左子节点遍历二叉树,存入一个序列。如果前后两个序列相等,那么说明二叉树是对称的。 [面试题60:把二叉树打印成多行](https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E6%8A%8A%E4%BA%8C%E5%8F%89%E6%A0%91%E6%89%93%E5%8D%B0%E6%88%90%E5%A4%9A%E8%A1%8C.py):引入两个队列。首先把当前层的节点存入到一个队列queue1中,然后遍历当前队列queue1,在遍历的过程中,如果节点有左子树或右子树,依次存入另一个队列queue2。然后遍历队列queue2,如此往复。 diff --git "a/Target Offer/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" "b/Target Offer/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" index 83c58c4..2d80777 100644 --- "a/Target Offer/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" +++ "b/Target Offer/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\213\344\270\200\344\270\252\347\273\223\347\202\271.py" @@ -8,25 +8,24 @@ def __init__(self, x): self.val = x self.left = None self.right = None - self.next = None + self.father = None #指向父节点的指针 class Solution: - def GetNext(self, pNode): - if pNode == None: - return - pNext = None - if pNode.right != None: - pRight = pNode.right - while pRight.left != None: - pRight = pRight.left - pNext= pRight - elif pNode.next != None: - pCurrent = pNode - pParent = pCurrent.next - while pParent != None and pCurrent == pParent.right: - pCurrent = pParent - pParent = pCurrent.next - pNext = pParent - return pNext + def GetNext(self, nNode): + if not nNode: + return None + + if nNode.right: #如果有右子树 + while nNode.left: + nNode = nNode.left + return nNode + + else: # 如果没有右子树 + while nNode.father: # 不停地去找父节点的左子节点是该节点的情况 + if nNode == nNode.father.left: + return nNode.father + nNode = nNode.father + + return None #都不满足情况,最后返回为空,是中序遍历的结尾 class Solution2: def GetNext(self, pNode): diff --git "a/Target Offer/\345\217\215\345\220\221\346\211\223\345\215\260\351\223\276\350\241\250.py" "b/Target Offer/\345\217\215\345\220\221\346\211\223\345\215\260\351\223\276\350\241\250.py" index ad0a21d..8b10b7a 100644 --- "a/Target Offer/\345\217\215\345\220\221\346\211\223\345\215\260\351\223\276\350\241\250.py" +++ "b/Target Offer/\345\217\215\345\220\221\346\211\223\345\215\260\351\223\276\350\241\250.py" @@ -17,6 +17,15 @@ def printListFromTailToHead(self, listNode): head = head.next return l +# 添加使用递归调用的方法,堆栈和递归是一样的 + def recursive(self, listNode): + if listNode.val != None: + if listNode.next != None: + self.recursive(listNode.next) + + print(listNode.val) + + node1 = ListNode(10) node2 = ListNode(11) node3 = ListNode(13) diff --git "a/Target Offer/\345\217\230\346\200\201\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.py" "b/Target Offer/\345\217\230\346\200\201\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.py" new file mode 100644 index 0000000..ec9aa8c --- /dev/null +++ "b/Target Offer/\345\217\230\346\200\201\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.py" @@ -0,0 +1,20 @@ +''' +和青蛙跳台阶问题类似,再做出一定程度扩展。 + +一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 + +这个问题写起来就很简单了,由数学归纳我们可以知道,一共有2^(n-1)种方案,所以就可以直接写代码 +''' + +class Solution: + def jumpFloor2(self, number): + if number == 0: + return 0 + + ans = 1 + if number == 1: + return 1 + else: + for i in range(1, number): + ans = 2*ans + return ans \ No newline at end of file diff --git "a/Target Offer/\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227.py" "b/Target Offer/\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227.py" index 1641cc1..c99c924 100644 --- "a/Target Offer/\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227.py" +++ "b/Target Offer/\346\226\220\346\263\242\351\202\243\345\245\221\346\225\260\345\210\227.py" @@ -5,29 +5,13 @@ # -*- coding:utf-8 -*- class Solution: - def Fibonacci(self, n): + def fibonacci(self, n): tempArray = [0, 1] + if n >= 2: for i in range(2, n+1): tempArray[i%2] = tempArray[0] + tempArray[1] return tempArray[n%2] - # 青蛙跳台阶, 每次可以跳1级或2级 - def jumpFloor(self, number): - # write code here - tempArray = [1, 2] - if number >= 3: - for i in range(3, number + 1): - tempArray[(i + 1) % 2] = tempArray[0] + tempArray[1] - return tempArray[(number + 1) % 2] - - def jumpFloorII(self, number): - ans = 1 - if number >= 2: - for i in range(number-1): - ans = ans * 2 - return ans test = Solution() -print(test.Fibonacci(100)) -print(test.jumpFloor(3)) -print(test.jumpFloorII(2)) \ No newline at end of file +print(test.fibonacci(100)) diff --git "a/Target Offer/\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227.py" "b/Target Offer/\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227.py" index a33dbe0..37947e8 100644 --- "a/Target Offer/\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227.py" +++ "b/Target Offer/\346\227\213\350\275\254\346\225\260\347\273\204\347\232\204\346\234\200\345\260\217\346\225\260\345\255\227.py" @@ -7,28 +7,44 @@ # -*- coding:utf-8 -*- class Solution: - def minNumberInRotateArray(self, rotateArray): - if len(rotateArray) == 0: + def minNumber(self, Array): + if len(Array) == 0: # 如果数组为空,返回0 return 0 front = 0 - rear = len(rotateArray) - 1 - minVal = rotateArray[0] - if rotateArray[front] < rotateArray[rear]: - return rotateArray[front] - else: - while (rear - front) > 1: - mid = (rear + front)//2 - if rotateArray[mid] > rotateArray[rear]: - front = mid - elif rotateArray[mid] < rotateArray[front]: - rear = mid - elif rotateArray[mid] == rotateArray[front] and rotateArray[front] == rotateArray[rear]: - for i in range(1, len(rotateArray)): - if rotateArray[i] < minVal: - minVal = rotateArray[i] - rear = i - minVal = rotateArray[rear] - return minVal + rear = len(Array) - 1 + + if Array[rear] > Array[front]: # 如果数组最后一个元素大于第一个元素,证明这个数组是不翻转的数组,直接返回第一个元素 + return Array[front] + + while (rear - front) > 1: + mid = (front + rear) // 2 # 二分法比较数组中间元素,之所以想到二分法是因为数组是有序的 + if Array[mid] < Array[rear]: + rear = mid + if Array[front] < Array[mid]: + front = mid + + if Array[front] == Array[mid] == Array[rear]: # 对数特殊情况数组的判断,即当首中尾元素都相同的时候,二分法失效,只能顺序查找 + mid = 0 + for i in range(1, len(Array)): + if Array[mid] < Array[i]: + continue + else: + mid = i + + return Array[mid] + + return Array[mid] + + +a = Solution() +Array = [3, 4, 5, 1, 2] +Array2 = [1, 2, 3, 4, 5] +Array3 = [1, 0, 1, 1, 1] +print(a.minNumber(Array)) +print(a.minNumber(Array2)) +print(a.minNumber(Array3)) + + # 书上方法 def minNumberInRotateArray2(self, rotateArray): if len(rotateArray) == 0: diff --git "a/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" "b/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" index bd15a41..e7429ae 100644 --- "a/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" +++ "b/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" @@ -40,29 +40,35 @@ def replaceSpace2(self, s): return return s.replace(' ', '%20') - # 书中给的思路 + # 书中给的思路,在原有字符串中替换,不许增加新的字符串 # 判断输入类型的时候,isinstance必须首先判断,因为如果输入为integer的话,没有len,就会直接报错 def replaceSpace3(self, s): - if not isinstance(s,str) or len(s) <= 0 or s == None: - return "" + if not isinstance(s, str) or len(s) <= 0 or s == 0: + return "出错了" + spaceNum = 0 for i in s: if i == " ": spaceNum += 1 + + IndexOfOriginal = len(s) - 1 + print(IndexOfOriginal) - newStrLen = len(s) + spaceNum * 2 - newStr = newStrLen * [None] - indexOfOriginal, indexOfNew = len(s) - 1, newStrLen - 1 - while indexOfNew >= 0 and indexOfNew >= indexOfOriginal: - if s[indexOfOriginal] == ' ': - newStr[indexOfNew-2:indexOfNew+1] = ['%', '2', '0'] - indexOfNew -= 3 - indexOfOriginal -= 1 + s = list(s) + spaceNum*2*[None] #替换空格增加三个元素,减少一个元素,实际上增加的是2个元素 + IndexOfNew = len(s) - 1 + + while IndexOfOriginal >=0 and IndexOfNew > IndexOfOriginal: + if s[IndexOfOriginal] == " ": + s[IndexOfNew - 2:IndexOfNew + 1] = ["%", "2", "0"] #因为是左闭右开,所以这里要有一个加1 + + IndexOfNew -=3 + else: - newStr[indexOfNew] = s[indexOfOriginal] - indexOfNew -= 1 - indexOfOriginal -= 1 - return "".join(newStr) + s[IndexOfNew] = s[IndexOfOriginal] + IndexOfNew -= 1 + IndexOfOriginal -= 1 + s = str(s) + return "".join(s) s = 'we are happy' diff --git "a/Target Offer/\347\224\250\344\270\244\344\270\252\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" "b/Target Offer/\347\224\250\344\270\244\344\270\252\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" index a46d001..843ca91 100644 --- "a/Target Offer/\347\224\250\344\270\244\344\270\252\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" +++ "b/Target Offer/\347\224\250\344\270\244\344\270\252\351\230\237\345\210\227\345\256\236\347\216\260\346\240\210.py" @@ -6,24 +6,28 @@ class Solution: def __init__(self): self.queue1 = [] self.queue2 = [] - def push(self, x): + + def push(self, nNode): if self.queue2 == []: - self.queue1.append(x) + self.queue1.append(nNode) else: - self.queue2.append(x) + self.queue2.append(nNode) + + # 如果队列1中有值,那么就把队列1中的值除最后一个外全部清空,只留下最后一个弹出 + # 同样的道理,队列1清空,队列2有值,那么弹出的时候,就把队列2中除最后一个元素外全部加入队列1,队列2最后一个元素弹出 def pop(self): - if not self.queue1 and not self.queue2: - return - if self.queue1 != []: - length = len(self.queue1) - for i in range(length-1): - self.queue2.append(self.queue1.pop(0)) - return self.queue1.pop() + if len(self.queue1) == 0 and len(self.queue2) == 0: + return else: - length = len(self.queue2) - for i in range(length-1): - self.queue1.append(self.queue2.pop(0)) - return self.queue2.pop() + if self.queue1 != []: + while len(self.queue1) > 1: + self.queue2.append(self.queue1.pop(0)) + return self.queue1.pop() + + else: + while(self.queue2) > 1: + self.queue1.append(self.queue2.pop(0)) + return self.queue2 P = Solution() P.push(10) diff --git "a/Target Offer/\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.py" "b/Target Offer/\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.py" new file mode 100644 index 0000000..68b31c6 --- /dev/null +++ "b/Target Offer/\351\235\222\350\233\231\350\267\263\345\217\260\351\230\266.py" @@ -0,0 +1,22 @@ +''' +一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。 +求该青蛙跳上一个n级的台阶总共有多少种跳法。 +''' + + +''' +这是一个斐波那契数列的变种,f(1) = 1; f(2) = 2; +f(n) = f(n-1) + f(n-2) +''' +class Solution: + def jumpFloor(self, number): + tempArray = [1, 2] + + if number >= 3: # number是从3开始迭代的 + for i in range(3, number + 1): + tempArray[(i + 1)% 2] = tempArray[0] + tempArray[1] # 3应当时更正tempArray的第一个位置,所以i+1 + return tempArray[(number + 1) %2] + + +test = Solution() +test.jumpFloor(100) \ No newline at end of file