剑指offer 算法练习笔记(一)

剑指offer 算法练习

第三题:从尾到头打印链表

题目描述

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

Python3单链表的简单操作

思路:

**简单的:**把链表先正序输入到列表中,再倒序放入另一个链表

# -*- 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
        l=[]
        while listNode:
            l.append(listNode.val)
            listNode=listNode.next
        return l[::-1]#逆序输出

递归:

def printListFromTailToHead(self, listNode):
    res=[]
    def printListnode(listNode):
        # write code here
        if listNode:
            printListnode(listNode.next)#先递归到最后一层
            res.append(listNode.val)#添加值,退出函数,返回到上一层函数中的这行,继续添加值
    printListnode(listNode)
    return res

第四题:重建二叉树

题目描述:

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路:

具体过程:

  1. 根据前序序列的第一个节点确定根节点.
  2. 根据根节点在中序序列中的位置分割出左右两个子序列
  3. 对左右子树分别使用同样的方法继续分解

例如:
前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in

  1. 根据当前前序序列的第一个结点确定根结点,为 1
  2. 找到 1 在中序遍历序列中的位置,为 in[3]
  3. 切割左右子树,则 in[3] 前面的为左子树, in[3] 后面的为右子树
  4. 则切割后的左子树前序序列为:{2,4,7},切割后的左子树中序序列为:{4,7,2};切割后的右子树前序序列为:{3,5,6,8},切割后的右子树中序序列为:{5,3,8,6}
  5. 对子树分别使用同样的方法分解

代码:

class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if len(pre) == 1:
            head = TreeNode(pre[0])
            head.left = None
            head.right = None
            return head
        head = TreeNode(pre[0])     
        temp1 = tin.index(pre[0])
        length = len(tin[:temp1])
        if temp1 == 0:
            head.left = None
        else:
            head.left = self.reConstructBinaryTree(pre[1:length+1], tin[:temp1])
        if length + 1 < len(pre):
            head.right = self.reConstructBinaryTree(pre[length+1:], tin[temp1+1:])
        else:
            head.right = None
        return head

第五题 用两个栈实现队列

题目描述:

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:

push:直接写入stack1

pop:当Stack2为空时,将stack1中的内容写入stack2,然后输出栈顶元素

# -*- 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):
        # return xx
        if len(self.stack2)==0:
            while self.stack1!=[]:
                 self.stack2.append(self.stack1[-1])
                 self.stack1.pop()
        pop = self.stack2[-1]
        self.stack2.pop()
        return pop
# -*- coding:utf-8 -*-
class Solution:
 def Fibonacci(self, n):
     # write code here
     result = {0:0, 1:1}
     def helper(n):
         if n in result:
             return result[n]
         res = helper(n-1) + helper(n-2)
         result[n] = res
         return res
     return helper(n)

二进制中1的个数

简单的思路:直接装换后输出里面1的个数

# -*- coding:utf-8 -*-
#简单的方法
class Solution:
    def NumberOf1(self, n):
        # write code here
        if n<0:
            n=n&0xffffffff # 换成补码
        return bin(n).count("1")

巧妙的思路:

# -*- coding:utf-8 -*-
#简单的方法
class Solution:
    def NumberOf1(self, n):
        # write code here
        count=0
        if n <0 :
            n=n&0xffffffff
        while  n!=0:
            n=n&(n-1)#通过巧妙地转换
            count+=1
        return count

数值的整数次方

比较简单的思路:

# -*- coding:utf-8 -*-
class Solution:
    def reOrderArray(self, array):
        # write code here
        ji=[]
        os=[]
        for i in array:
            if i%2:
                ji.append(i)
            else:
                os.append(i)
        return ji+os

链表中倒数第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
        res=[]
        while head!=None:
            res.append(head)
            head=head.next
        if len(res)<k or k<1:
                return None
        return res[-k]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值