7 天掌握算法面试必考知识点

视频课已上传B站 【7 天掌握算法面试必考知识点 - 覃超老师
覃超老师的算法课很实在,干货满满!虽然这只是体验课,还没购买正式课,认真听还是会有很大收获的!

学习技巧:
1)好记性不如烂笔头, 因此请尝试
2)给每一道自己写过,看过的题目写一篇解题报告,
3)对相关一类题型的总结报告,

算法对于程序员的重要性不言而喻。希望这 7 天的学习能够帮助你掌握高效的学习方法,逐渐把算法能力强化为自己的内功。我也从来不相信“速成”、“捷径”之类的宣传语,我们想要把算法学明白,就需要付出不亚于任何人的努力。开课之前,也请你做好充足的时间和心理准备。学习是自己的事情,送到嘴边的饭还得你自己细嚼慢咽才能消化,所以更多的还是需要你自己练习,自己思考。
在这里插入图片描述
Leecode解题完毕,将网址中的-cn去掉,可以去到国际站看更多的解题思路

编程题

节选视频中讲解的两道编程题,和链接中的三道编程题,老师多用java编写,我比较习惯用python。有的就用老师说的解题思路换个语言编写,有的是参考其他解题思路写的,还有自个想的(可能略挫,见谅!如有错 / 有不恰当的地方 / 有更好优化方法的 都可以留言讨论)

1.移动0

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序
【链接】 https://leetcode-cn.com/problems/move-zeroes/

'''
示例:
输入: [0,1,0,3,12]		输出: [1,3,12,0,0]

说明:
必须在原数组上操作,不能拷贝额外的数组。尽量减少操作次数。
'''
def moveZeroes(nums):	# 方法1
    """
    :type nums: List[int]
    :rtype: None Do not return anything, modify nums in-place instead.
    """
    # 我假设输入[1,0,3,0,5],下面也是针对这个序列的分析
    j = 0  
    for i in range(len(nums)): 
        print('nums[i] = ',nums[i])    
        if nums[i] != 0:          
            nums[j] = nums[i]   # 先查找非0的,用新下标j存着
            print("if-1",nums)
            
            # 遇到0的时候,i会+1,j不会,那i就会比j大,在if-1中的nums还没调整好
            # if-2这里再去调整新nums,如我刚才前3是[1,3,3],调整后是[1,3,0]
            # 至少到这步,也完成了前3个数的 0的后移

            if i!=j:    
                nums[i] = 0
                print("if-2",nums)
            j = j+1
    print("nums result = ",nums)

    # i=0 j=0   num[i]=1
    # if-1:num = [1,]    

    # i=1 j=1   num[i]=0
    
    # i=2 j=1   num[i]=3 num[j]=3
    # if-1:num = [1,3,3]   
    # if-2:num = [1,3,0]   

    # i=3 j=2   num[i]=0 num[j]=/   这里的总nums是[1,3,0,0,5]
    # i=4 j=2   num[i]=5 num[j]=5
    # if-1:num = [1,3,5,0,5]   
    # if-2:num = [1,3,5,0,0]
    # 第2个if是把nums的最后一个数(最新的i下标)变0,完成后移操作
def moveZeroes2(nums):	# 方法1更快
    for i in range(len(nums)):
        if nums[i]==0:
            nums.remove(0)
            nums.append(0)
    print(nums)
    
nums = [1,0,3,0,5]
moveZeroes(nums)

# 思路2:新开个数组存放(不符合题目要求)

2.删除排序数组中的重复项

给定一个 排序(已排序好的) 数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
【链接】 https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

'''
示例 1:
给定数组 nums = [1,1,2], 
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 你不需要考虑数组中超出新长度后面的元素。

示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。

'''
class Solution(object):
    def removeDuplicates(nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        p = 0
        for q in range(1,len(nums)):
            if nums[p] != nums[q]:
                p=p+1
                nums[p] = nums[q]
            # print(p)
        del nums[p+1:len(nums)]	# 删除后面糟糕的数据,才能返回移除后数组的新长度,否则执行出错
        print(nums)

nums = [0,0,1,1,1,2,2,3,3,4]
Solution.removeDuplicates(nums)

附上一种自个画的双指针图,其中q+1是每次循环都会进行的操作,就不用写了
在这里插入图片描述

3.二叉树的前序遍历

给定一个二叉树,返回它的 前序 遍历。
链接】https://leetcode-cn.com/problems/binary-tree-preorder-traversal/

'''
示例:
输入: [1,null,2,3]  
   1
    \
     2
    /
   3 
输出: [1,2,3]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?
'''

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def preorderTraversal(self, root):# 根左右
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        stack,rst = [root],[]
        while stack:
            i = stack.pop()
            if isinstance(i,TreeNode):
                stack.extend([i.right,i.left,i.val])	# 一句搞定
            elif isinstance(i,int):
                rst.append(i)
        return rst

4.括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
【链接】https://leetcode-cn.com/problems/generate-parentheses/

先来看老师的解法,严格按照递归模板来做的哈
01 初级版本:生成n=3(共2(2x3)=64种)的所有组合
在这里插入图片描述
02 中级版本

  • terminator 终止条件:‘(’ 和 ‘)’都用完了,再输出 s
  • drill down 下探到下一层和处理一起进行:判断两个
    • 左括号’(’ 只要还没用完(3个),那就可以添加
    • 右括号’)’ 必须小于左括号的个数时才能添加

在这里插入图片描述
在这里插入图片描述
然后呢,我用py写一个
按照下面这个套路
在这里插入图片描述

class Solution():
    def generateParenthesis(self,n):
        """
        :type n: int
        :rtype: List[str]
        """
        result = []
        par_str = ''
        def generate(left,right,n,par_str):
            if (left==n) and (right==n):    # terminator
                result.append(par_str)
                # print(par_str)
                # return result
            if left<n:
                generate(left+1, right, n, par_str+'(')
            if left>right:
                generate(left, right+1, n, par_str+')')
        generate(0,0,n,par_str)

        return result
    # def generateParenthesis(self,n):    # 参考
    #     res = []
    #     cur_str = ''
    #     def dfs(cur_str, left, right, n):
    #         """
    #         :param cur_str: 从根结点到叶子结点的路径字符串
    #         :param left: 左括号已经使用的个数
    #         :param right: 右括号已经使用的个数
    #         :return:
    #         """
    #         if left == n and right == n:
    #             res.append(cur_str)
    #             return
    #         if left < n:
    #             dfs(cur_str + '(', left + 1, right, n)
    #         if right < n:
    #             dfs(cur_str + ')', left, right + 1, n)
    #     dfs(cur_str, 0, 0, n)

也可以看很多国内外牛人解法
在这里插入图片描述

5.二叉树的最大深度

给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
【链接】https://leetcode-cn.com/problems/maximum-depth-of-binary-tree

'''
示例:
给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7
返回它的最大深度 3 。
'''

通过下面这个的动图和静图可以较清晰的表示 递归算法 的解题思路了
在这里插入图片描述
在这里插入图片描述

'''
很多二叉树的题目,用递归写起来就非常简单。
再来分析下递归的两个条件:

递归终止条件:当节点为空时返回
再次递归计算 max( 左节点最大高度,右节点最大高度)+1
终止条件很好理解,节点为空了,就返回0,也就是高度为0。
'''

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def maxDepth(self, root):   # 法1
        """
        :type root: TreeNode
        :rtype: int
        """
        # 递归:max(遍历左,遍历右) +1
        if root is None:   
            return 0 
        else: 
            left_height = self.maxDepth(root.left) 
            right_height = self.maxDepth(root.right) 
            return max(left_height, right_height) + 1 
    def maxDepth(self, root):   # 法2 j版
        # 如果节点为空,那么深度就是0
        if(not root):
            return 0
        # 否则递归的计算  max(左子树的最大深度,右子树的最大深度)
        # 不管左子树,右子树是否为空,他们的父节点肯定是不为空
        # 所以计算出的总深度要把父节点也要加上,也就是 +1
        return max( self.maxDepth(root.left), self.maxDepth(root.right) ) + 1

相关链接

  • Day1.参考链接
    如何理解算法时间复杂度的表示法【https://www.zhihu.com/question/21387264】
    Master theorem 【https://en.wikipedia.org/wiki/Master_theorem_(analysis_of_algorithms)】
    主定理 【https://zh.wikipedia.org/wiki/%E4%B8%BB%E5%AE%9A%E7%90%86】

  • Day2.参考链接
    Java 源码分析(ArrayList)【http://developer.classpath.org/doc/java/util/ArrayList-source.html】
    Linked List 的标准实现代码【https://www.geeksforgeeks.org/implementing-a-linked-list-in-java-using-class/】
    Linked List 示例代码【http://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/code/LinkedList.java】
    Java 源码分析(LinkedList)【http://developer.classpath.org/doc/java/util/LinkedList-source.html】
    LRU Cache - Linked list: LRU 缓存机制【https://leetcode-cn.com/problems/lru-cache/】
    Redis - Skip List:跳跃表、为啥 Redis 使用跳表(Skip List)而不是使用 Red-Black?【https://www.zhihu.com/question/20202931】
    跳跃表【https://redisbook.readthedocs.io/en/latest/internal-datastruct/skiplist.html】

  • Day3.两道编程题
    删除排序数组中的重复项【https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/】
    盛最多水的容器【https://leetcode-cn.com/problems/container-with-most-water/】

  • Day4.参考链接
    二叉搜索树 Demo【https://visualgo.net/zh/bst?slide=1】
    思考题:树的面试题解法一般都是递归,为什么?

  • Day5.两道编程题
    N 叉树的前序遍历【https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/】
    二叉树的前序遍历【https://leetcode-cn.com/problems/binary-tree-preorder-traversal/】
    参考链接:树的遍历 Demo【https://visualgo.net/zh/bst?slide=1】

  • Day6.参考链接
    递归代码模板:https://shimo.im/docs/EICAr9lRPUIPHxsH/read

    • Python 代码模板
    def recursion(level, param1, param2, ...): 
        # recursion terminator 
        if level > MAX_LEVEL: 
    	   process_result 
    	   return 
        # process logic in current level 
        process(level, data...) 
        # drill down 
        self.recursion(level + 1, p1, ...) 
        # reverse the current level status if needed
    
    • Java 代码模板
    public void recur(int level, int param) {
    	// terminator 
    	if (level > MAX_LEVEL) { 
    	    // process result 
    	    return; 
    	}
     	// process current logic 
    	process(level, param); 
    	// drill down 
    	recur( level: level + 1, newParam); 
    	// restore current status 
    }
    
    • c++代码模板
    void recursion(int level, int param) { 
    	// recursion terminator
    	if (level > MAX_LEVEL) { 
    		// process result 
    	return ; 
    	// process current logic 
    	process(level, param);
    	// drill down 
    	recursion(level + 1, param);
    	// reverse the current level status if needed
    }
    
  • Day7.两道编程题
    二叉树的最大深度【https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/】
    验证二叉搜索树【https://leetcode-cn.com/problems/validate-binary-search-tree/】

  • 直播
    https://github.com/Snailclimb/JavaGuide
    https://github.com/CyC2018/CS-Notes
    https://juejin.im/entry/6844903474195333128
    费曼学习法
    光看不练
    系统设计

    • github: https://github.com/donnemartin/system-design-primer
    • 中文: https://github.com/donnemartin/system-design-primer/blob/master/README-zh-Hans.md

homework

Day5

  1. 【二叉树的中序遍历】https://leetcode-cn.com/problems/binary-tree-inorder-traversal/
  2. 【二叉树的前序遍历】https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
  3. 【N叉树的后序遍历】https://leetcode-cn.com/problems/n-ary-tree-postorder-traversal/
  4. 【N叉树的前序遍历】https://leetcode-cn.com/problems/n-ary-tree-preorder-traversal/
  5. 【N叉树的层序遍历】https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/

Day 7

  1. 【翻转二叉树】https://leetcode-cn.com/problems/invert-binary-tree/description/
  2. 【验证二叉搜索树】https://leetcode-cn.com/problems/validate-binary-search-tree/
  3. 【二叉树的最大深度】https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
  4. 【二叉树的最小深度】https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
  5. 【二叉树的序列化与反序列化】https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/
  6. 【二叉树的最近公共祖先】https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
  7. 【从前序与中序遍历序列构造二叉树】https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
  8. 【组合】https://leetcode-cn.com/problems/combinations/
  9. 【全排列】https://leetcode-cn.com/problems/permutations/
  10. 【全排列 II】https://leetcode-cn.com/problems/permutations-ii/

五步刷题法(五毒神掌

刷题第一遍:
5分钟:读题+思考(建议不要超过15分钟)

直接看解法:注意!多解法,比较优劣
背诵、默写好的解法

第二遍:
马上自己写–> LeetCode提交 debug至完成

多种解法比较、体会–>优化!
看时间空间 效率 (执行时间和内存消耗)

第三遍:
过了一天后,再重复做题
不同解法的熟练程度–>专项练习

第四遍:
过了一周:反复回来练习相同题目
对于不熟的题目专项练习。

第五遍:
如果有面试,面试前一周进行恢复式训练

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值