练习全部只针对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