Day1:剑指offer

简单自我反思一下哈~
“金三银四”满天飞,尝试自己去投实习,发现技术岗笔试题自己弱爆了,怎么能短期提升写code能力呢?我真的很惆怅啊,以前以为刷刷题,很简单啊,真正去试了leecode,牛客网里面的‘剑指offer’,才发现根本不是能速成的,哭死~~~~~~~
担心找不到实习,找不到工作,这么多年的书岂不是白读了,一路以来的学校也还不差(T_T),我该怎么办啊?担心,愁,自己很多想做的事现在都不敢去碰(譬如一直想练习的吉他,想自学考证的JLPT),怕时间没有用在刷题,看算法,看数据结构等等,这些找实习,找工作需要的技能上。想想,能很容易的开导别人,而对自己总是 ‘很多道理知道得不得了,依然无法开导自己’。。。
想到现在,也不知道怎么办,发呆心里更是慌得不得了。现在开始,每天坚持总结5到code题,结果如何,我都不敢去想,实在不行,就去桥底下贴膜吧~
人生好艰难啊,什么时候可以变好呢?

补一下昨天的题

[剑指offer开始]
1.找出数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
e.g,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

#自己写的时间复杂度O(n^2), 空间复杂度O(1)
#思想很low,精华是:怎么跳出双层for循环

#输入的方式一(笔试的时候是need自己写输入的,需记住)
n = int(input())
arr = [int(i) for i in input().split()] #type(arr)

def findReapteNum(arr1):
    for i in range(n-1):
        for j in range(i+1,n):
            if arr1[i] == arr1[j]:
                print(arr1[i])   #return arr1[i] 都可以输出
                break
        else:
            continue
        break

findReapteNum(arr)
#思路二: 可以先排序,时间复杂度O(nlogn),再找就简单了
#三
解析版:时间复杂度O(n),空间复杂度O(1)
每个数字最多只要交换两次就能找到属于它的位置
#最后的arr会变动,不是最初输入的arr
def duplicate( arr):
    for i, val in enumerate(arr):  # i:index  val:value
        while i != val:  # 下标 不等于 arr[下标]
            if arr[val] == val:
                return val
                break
            arr[i], arr[val] = arr[val], arr[i]
            val = arr[i]     #仍然在while循环中,不能漏掉
     return None  #完整性
duplicate( arr)

1.2 不修改数组找出重复的数字
给定一个长度为 n+1 的数组nums,数组中所有的数均在 1∼n 的范围内,其中 n≥1。
请找出数组中任意一个重复的数,但不能修改输入的数组。
e.g:给定 nums = [2, 3, 5, 4, 3, 2, 6, 7]。 返回 2 或 3。如果只能使用 O(1) 的额外空间,该怎么做呢?

#说明
题解里的 ‘二分’思想没琢磨透,不知道这个办法是怎么出来的,1里面自己的low办法,就能得到结果。学一学‘二分’的一个过程吧,就当
#二分(大致这个思路吧)
l,r =0, len(n)
while l<r:
    mid = 1+l >>1  #运算顺序:先加减,再移位
    for i,x in enumerate(arr):
        if l<=i<=mid and x>arr[mid]:
            l=i
        elif mid < i <= r and x < arr[mid]:
            r=mid
        else:
            l=l+1
    return ...           

2.二维数组中的查找
在一个二维数组中,每一行都按照从左到右递增的顺序排序。每一列都按照从上到下递增的顺序排序。给定一个整数,查找数组中是否存在该整数。
输入这样一个二维数组和一个整数,判断数组中是否含有该整数。
[ [1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15] ]

#直接法,不考虑计算成本,时间复杂度O(n)
def find(target, array):
    row, col = len(array), len(array[0])
    for i in range(row):
        for j in range(col):
            if target == array[i][j]:
                return True
                break   #可不要,要,节约计算,找到后就停止了(当然只跳出内部for循环;跳出双层,参照题1)
    return False
#这题很好:告诉思路-删除法,每次消灭掉一行或者一列,逐步缩小范围;
#消灭手段要choose好,只能右上or左下(这两处点的一条是递增,一条是递减,重要特点)
def searchArray(arr,N):
    if not array:
        return False  # 对数组的处理
    row, col = 0, len(array[0]) - 1   #col作为下标,一定注意要 -1(这里的bug调了好久,真的是自己)
    #下面row的-1 也是因为对应下标[敢于去想,去调试,bug都会犯,总结一点,要快速改过来,笔试时间是有限的]
    while row <= len(array) - 1 and col >= 0:  # 条件要想清楚(下面row +=1,所以row<=len(arr)-1)
        if target == array[row][col]:
            return True
        elif target < array[row][col]:
            col -= 1
        else:          # target > arr[row][col]
            row += 1
    return False

补充一个输入操作:

target = int(input())
array = []            #下面用append函数一定对应这个 提前分配内存
for i in range(n):   #假设是n*m矩阵
    array.append(list(map(int,input().split())))
  1. 替换空格
    请实现一个函数,把字符串中的每个空格替换成"%20"。
#没想明白题解里面的 从后往前,难道不能也是先算出扩充后的总长度,再从前往后替换不行吗???
#python里面有函数,就直接用了,毕竟solve问题最重要,有现有的就用呗
def replaceSpace(s):
    if type(s)!= str: return     #等价于return None
    return s.replace(' ','%20')
  1. 从尾到头打印链表
    输入一个链表的头结点,按照 从尾到头 的顺序返回节点的值。
#list.reverse() 是没有返回值的,所以必须按以下处理
#链表不是连续的内存,所以需要遍历
#先转成list,再用list.reverse() 
# 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 not listNode: return []
        res = []
        while listNode:   #等价于listNode != None
            res.append(listNode.val)
            listNode = listNode.next
        res.reverse()  
        return res

\

def printListFromTailToHead(listNode):
    if not listNode: return 
    res = []
    res.recursion(listNode)
    return res

#递归: 每访问一个结点时,先递归输出它后面的结点,再输出该节点自身
#递归输出:像洋葱 从内往外 一层层剥开
def recursion(listNode):
    #if not listNode: return  #严谨性,可加可不加
    recursion(listNode.next)
    res.append(listNode.val)   #结点在移动,listNode表示的是结点指针的遍历
  1. 重建二叉树
    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
    例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

知识点:二叉树父节点和子节点之间用指针链接。(同链表)返回根节点[头指针]就是整个树了。

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

#这个题就需要去 mock套路
#题解说:二叉树的遍历,靠递归和循环实现
#这个重构的题,对递归很好的诠释
class Solution:  # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        if not pre or not tin: return
        root = TreeNode(pre[0])
        mid = tin.index(pre[0])
        root.left = self.reConstructBinaryTree(pre[1:mid + 1],tin[:mid])
        root.right = self.reConstructBinaryTree(pre[mid + 1:],tin[mid + 1:])
        return root

————————————————
版权声明:本文为CSDN博主「手机用户2388565755」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012114900/article/details/105306065

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值