剑指offer牛客网练习20200101

练习全部只针对python,因为我本来就是拿来练python的,所以可能没有C的那种解题那么难,要不要直接用做好的轮子,我自己根据情况决定。python是我目前用过时间最短的语言,所以我就是个小白,我也不是计算机、数学专业的,高深的算法都不会,不要喷我。

新年一天练习的感觉:

通过率不知道为啥比学C的时候高了好多= =经常是我先试试,就过了

可能是对python的查时间不够严格?还是查边界不严格

还是我没认真理解题意啊

我发现,有时候他们讲的那种算法名称我不知道,但是我想的算法和他们是一样的,我的理论基础真的太弱了

1. 二维数组查找

def findt(target,array,i,j):
    #print(i,j,array[i][j])
    r=False
    z=False
    if i>=len(array) or j>=len(array[0]):
        return False
    else:
        if array[i][j]==target:
            return True
        else:
            if array[i][j]<target:
                r=findt(target,array,i,j+1)
                if not r:
                    z=findt(target,array,i+1,j)
    return r or z
class Solution:
    # array 二维列表
    def Find(self,target, array):
        # write code here
        return findt(target,array,0,0)

使用的是迭代的方法,并没有从中间开始判断

讨论区里面有人的代码如下,思路更为清晰明了

从左下角元素往上查找,右边元素是比这个元素大,上边是的元素比这个元素小。于是,target比这个元素小就往上找,比这个元素大就往右找。如果出了边界,则说明二维数组中不存在target元素。
链接:https://www.nowcoder.com/questionTerminal/abc3fe2ce8e146608e868a70efebf62e?f=discussion
来源:牛客网

# -*- 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

2.从尾到头打印链表

说实话,我到现在对python的数据类型还是很迷茫,而且我还没有完全搞懂牛客网输入的到底是啥

# -*- 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
        if listNode is None:
            return []
        else:
            node=listNode.next
            l=[listNode.val]
            while(node is not None):
                l.append(node.val)
                node=node.next
            return l[::-1]

讨论区的一个人的

链接:https://www.nowcoder.com/questionTerminal/d0267f7f55b3412ba93bd35cfa8e8035?f=discussion
来源:牛客网


看懂了,确实简洁,迭代


# -*- 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 
    if listNode is None: 
        return [] 
    return self.printListFromTailToHead(listNode.next) + [listNode.val]

3.重建二叉树

???其实我莫名其妙的就通过了,之前不通过是一些python的基本语法错误,中间不知道pre咋传参,因为左节点确定的时候,传入右边的create应该要改变pre,后来决定利用pre是个指针这个特性,改变一个pre所有的都会改变

讨论区python的思路和我的类似

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
def create(pre,tin):
    if len(tin)==0:
        return None
    new=TreeNode(pre[0])
    index=tin.index(pre[0])
    pre.pop(0)
    new.left=create(pre,tin[0:index])
    new.right=create(pre,tin[index+1:])
    return new
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        return create(pre,tin)

4.两个栈实现队列

em..说实话一开始没有懂题目到底要怎么实现,不是不懂栈和队伍,而是不知道在python中要怎么通过那个验证正误的程序,看了一下讨论区。

思路是:

入队:将元素进栈A(不需要判断A/B是否为空)

出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;

 如果不为空,栈B直接出栈。

另外还有个扩展两个队列实现栈:

入栈:元素直接进队A

出栈:判断A是否为空,为空,B的出队到A里,最后一个元素就是

判断A是否为一个元素,是,则直接出

判断A>1,是,则需要A出队后入队B的最后一个元素即可

class Solution:
    def __init__(self):
        self.stack1 = []
        self.stack2 = []
    def push(self, node):
        # write code here
        self.stack1.append(node)
    def pop(self):
        if not len(self.stack2)==0:
            return self.stack2.pop()
        else:
            while len(self.stack1)>1:
                self.stack2.append(self.stack1.pop())
            return self.stack1.pop()

5.旋转数组

最开始用了以下min函数哈哈哈

之后用的是比较法,如果当数组后一个元素小于前一个元素,后一个元素一定是最小的,当然不排除非逆序、元素只有一个的情况

注意存在数组元素只有一个的可能,复杂度是O(n)

但是我看了讨论区是在考二分法?以下是我自己写的

# -*- coding:utf-8 -*-
class Solution:
    def minNumberInRotateArray(self, rotateArray):
        # write code here
        if len(rotateArray)==0:
            return 0
        else:
            temp=rotateArray
            for i in range(1,len(rotateArray)):
                if rotateArray[i-1]>rotateArray[i]:
                    return rotateArray[i]
            return rotateArray[0]

之后参考了以下的二分法解析,反正我想不出来

https://xxoo521.com/2019-12-24-xuan-zhuan-shu-zu/

6.斐波那契数列

。。。自己用了简单方法实现后,看了看评论区,他们在说什么啊啊啊啊,我怎么感觉他们说的我都没懂,而且搞得很复杂的样子= =为啥啊啊啊,是不是我刷题的方式有问题,什么柯里化?尾递归?那都是啥啊,为啥会栈溢出??

别人的动态规划,这个我看懂了

链接:https://www.nowcoder.com/questionTerminal/c6c7742f5ba7442aada113136ddea0c3?f=discussion
来源:牛客网

class Solution {
public:
    int Fibonacci(int n) {
        int f = 0, g = 1;
        while(n--) {
            g += f;
            f = g - f;
        }
        return f;
    }
};

我自己的

# -*- coding:utf-8 -*-
class Solution:
    def Fibonacci(self, n):
        # write code here
        l=[1,1]
        if n==0:
            return 0
        for i in range(2,n):
            l.append(l[i-1]+l[i-2])
        return l[n-1]

7.跳台阶

我看了一下,发现考点是递归= =我想着就是用高中的排列组合公式,没有想用递归,但是还是用了递归来求阶乘。

# -*- coding:utf-8 -*-
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)
class Solution:
    def jumpFloor(self, number):
        # write code here
        second=number/2
        result=0
        while(second>=0):
            one=number-second*2
            result=result+(factorial(second+one)/(factorial(second)*factorial(one)))
            second=second-1
        return result        

讨论区,噢,发现是斐波那契数列,好吧,看来是我没注意找规律了,而且我发现大家用的程序很容易就不通过,是因为我用python所以时间没有限制吗?

8.变态跳台阶

= =我看到题直接放弃了,然后选择了讨论区,噢原来又是数学题= =找规律

链接:https://www.nowcoder.com/questionTerminal/22243d016f6b47f2a6928b4313c85387?f=discussion
来源:牛客网

因为n级台阶,第一步有n种跳法:跳1级、跳2级、到跳n级
跳1级,剩下n-1级,则剩下跳法是f(n-1)
跳2级,剩下n-2级,则剩下跳法是f(n-2)
所以f(n)=f(n-1)+f(n-2)+...+f(1)
因为f(n-1)=f(n-2)+f(n-3)+...+f(1)

所以f(n)=2*f(n-1)

# -*- coding:utf-8 -*-
class Solution:
    def jumpFloorII(self, number):
        # write code here
        l=[1]
        for i in range(1,number):
            l.append(l[i-1]*2)
        return l[number-1]

9.矩形覆盖

依旧是那个数列,注意0,1的边界

# -*- coding:utf-8 -*-
class Solution:
    def rectCover(self, number):
        # write code here
        f,g=1,1
        if number==0:
            return 0
        while(number>0):
            g=g+f
            f=g-f
            number=number-1
        return f

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就是一只白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值