数据结构算法编程
1.打印一个链表,从尾到头打印链表
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: # 返回从尾部到头部的列表值序列,例如[1,2,3] def printListFromTailToHead(self, listNode): # write code here cur = listNode l=list() # l=[] while cur: l.append(cur.val) cur=cur.next return l[::-1]
2、用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型
思路:两个栈S1,S2,分别作为存储区和缓冲区
入队时,将元素压入s1。
出队时,将s1的元素逐个“倒入”(弹出并压入)s2,将s2的顶元素弹出作为出队元素,之后再将s2剩下的元素逐个“倒回”s1。
见下面示意图:
# -*- coding:utf-8 -*- class Solution: def __init__(self): self.stack1 = [] self.stack2 = [] def push(self, node): # write code here self.stack1.append(node) def pop(self): if self.stack2 ==[]: while self.stack1: self.stack2.append(self.stack1.pop()) return self.stack2.pop() # return xx
3 .找数组中的最小数
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
思路:循环len(array)-1次,采用冒泡排序的思想,比较array[i]与array[i+1]的大小,如果前者比后者小,就后移,循环完成后最末尾的数值就是此序列的最小值
x# -*- coding:utf-8 -*- class Solution: def minNumberInRotateArray(self, rotateArray): # write code here n = len(rotateArray) if n>=1: for i in range(0,n-1): if rotateArray[i]<rotateArray[i+1]: rotateArray[i],rotateArray[i+1]=rotateArray[i+1],rotateArray[i] return rotateArray.pop() else: return 0
4.二维数组查找目标
描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
# -*- coding:utf-8 -*- class Solution: # array 二维列表 def Find(self, target, array): # write code here rows = len(array) - 1 cols= len(array[0]) - 1 i = rows j = 0 while j<=cols and i>=0: if target<array[i][j]: i -= 1 elif target>array[i][j]: j += 1 else: return True return False
5. 斐波那契数列
裴波那数列:f(0) = 1,f(1) = 1,f(n) = f(n-1) + f(n-2)
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
# -*- coding:utf-8 -*- class Solution: def __init__(self): self.lists=[0,1] def Fibonacci(self, n): # write code here if n==0: return 0 elif n==1: return 1 elif n>1: count =n while count-1>0: lens=len(self.lists) self.lists.append(self.lists[lens-1]+self.lists[lens-2]) count-=1 return self.lists[n]
6. 跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
思路:如果第一步跳1阶,那么还剩下f(n-1);如果第一步跳2阶,那么还剩下f(n-2);f(1)=1,f(2)=2,就是递归的裴波那契数列
改进了上一个裴波那契数列的代码
class Solution: def jumpFloor(self, number): # write code here a=[1,2] if number==1: return 1 elif number==2: return 2 elif number>2: for i in range(2,number): a.append(a[i-1]+a[i-2]) return a[number-1]
或者不记录前n项,直接求第n项
class Solution: def jumpFloor(self, number): # write code here a = 1 b = 1 for i in range(number): a,b = b,a+b return a
6. 变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法
思路: Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+..........+Fib(n-n)=Fib(0)+Fib(1)+Fib(2)+.......+Fib(n-1)
又因为Fib(n-1)=Fib(0)+Fib(1)+Fib(2)+.......+Fib(n-2)
两式相减得:Fib(n)-Fib(n-1)=Fib(n-1) =====》 Fib(n) = 2*Fib(n-1) n >= 2
递归等式如下:
class Solution: def jumpFloorII(self, number): # write code here return 2**(number-1)
7. 打印链表中倒数第k个节点
思路:先求出链表的长度n,倒数第k个即顺数n-k个,通过循环n-k次就可以找到此节点
需要考虑两个特殊情况:k大于n或小于等于0;链表是空链表。
还有一个问题就是头结点,链表和栈以及二叉树都是整体赋值过去,并没有头结点属性
(1)对于空链表,返回链表本身
(2)当k大于n,返回链表末尾的值
(3)当n大于k,则循环n-k次后返回当前节点
# -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def FindKthToTail(self, head, k): # write code here n = self.length(head) if n==0: return head index = n-k cur = head if index<0: for i in range(n): cur = cur.next return cur else: for i in range(index): cur = cur.next return cur def length(self,head): cur =head count = 0 while cur: cur = cur.next count = count+1 return count
看到一个网友超简便的方法,新建一个list反存原链表,再通过索引直接取出来。此处的list就是一个顺序表
8、栈的压入和弹出
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
注意:没好好省题,并不是存完再取出来,可以边存边弹出,再存再弹出
思路:新建一个缓存区,放入入栈元素,并与出栈最后一个判断,相等就剔除,不等就压栈存入下一个元素再判断,直到缓存区为空
class Solution: def IsPopOrder(self, pushV, popV): if not pushV or len(pushV)!=len(popV): return 0 stack=[] for i in pushV: stack.append(i) while len(stack) and stack[-1]==popV[0]: stack.pop() popV.pop(0) if len(stack): return 0 return 1
9、输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
思路:找到大的树,依次循环结点去比对小子树的跟结点,直到相同。
正确的是:递归循环