数据结构算法编程

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:我们约定空树不是任意一个树的子结构)

思路:找到大的树,依次循环结点去比对小子树的跟结点,直到相同。

正确的是:递归循环

posted @ 2018-06-09 17:14  bethansy  阅读(317)  评论(0编辑  收藏  举报