首页 > 其他分享 >code_summary

code_summary

时间:2024-02-27 18:14:19浏览次数:22  
标签:遍历 元素 summary 链表 code 二叉树 数组 指针

字符串

  • 几个库函数的时间复杂度:reverse/split, O(n);
  • 双指针法:反转字符串、替换空格;在数组、链表中更常用
  • 滑动窗口法,配合哈希表,计数器等:用于寻找子串相关的题目;
  • KMP:用前缀表来对目标串的重复子串进行标记,减少滑动搜索时的后退步数;

链表

  • 链表的种类主要为:单链表,双链表,循环链表

  • 链表的存储方式:链表的节点在内存中是分散存储的,通过指针连在一起。

  • 链表是如何进行增删改查的。

  • 数组和链表在不同场景下的性能分析。

  • 链表的定义: python: class ListNode(object): self.val = val, self.next=next

  • 多使用虚拟头结点;pre = ListNode(next=head)

  • 多使用双指针:尤其是存在一个值index时,双指针多遍历几遍,就能O(n) 时间,O(1)空间中获得结果;

双指针法

使用双指针法能展现出效率的优势:通过两个指针在一个for循环下完成两个for循环的工作

  • 使用场景:
    • 数组:删除数字元素(都从0开始,fast!=val时,复制到slow),反转数组(双指针两边向中间),替换空格(从后向前替换),
    • 链表:存在一个值index时,双指针多遍历几遍,就能O(n) 时间,O(1)空间中获得结果;
    • N数之和篇:可以用哈希法,但是比较难,对空间占用更大;双指针注意a,b,c三个数字的去重操作;
  • 常见使用方式:
    • 快慢指针:快指针每次移动两步,慢指针每次移动一步,通过快慢指针的相对移动找到特定位置的节点。
      • 题目:在链表中解决环形链表、链表中点、链表倒数第 k 个节点等问题时常用快慢指针,
    • 对撞指针:在有序数组中!通过左右指针同时向中间移动,根据元素大小的比较来调整指针位置。
      • 题目:解决两数之和、三数之和; 两数平方和
    • 滑动窗口:通过维护一个窗口区间,通过移动左右指针来调整窗口大小。
      • 在数组或字符串中解决子数组最大值、子字符串最大长度等问题时常用滑动窗口;
      • LeetCode 209. 长度最小的子数组,LeetCode 76. 最小覆盖子串 ;找到字符串中不含重复字符的最长子串。
    • 其他:
      • 合并两个有序数组:将两个有序数组合并为一个有序数组时,可以使用双指针法,一个指针指向第一个数组的末尾,另一个指针指向第二个数组的末尾,根据元素大小的比较来合并数组。
      • 回文字符串判断:判断一个字符串是否为回文字符串时,可以使用双指针法,一个指针从字符串头部开始,另一个指针从字符串尾部开始,同时向中间移动并比较对应位置的字符。

栈和队列

  • 栈:可以用栈来实现递归:栈里面的相邻元素,符合一定条件时就消除(或者运算),持续到最后;
    • 递归的实现是栈:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,
  • 逆波兰表达式:输入的列表是后缀表达式,其实是用后序遍历的方式把二叉树序列化了;
    • 数字元素放入栈,碰到运算符就pop2个进行运算;
    • 顺序和优先级的问题:后缀表达式天然对计算机友好,不用处理;
  • 单调队列:在动态数据流中维护一组元素,并保持元素的单调递增或单调递减;
    • 用途:在解决一些需要在滑动窗口中找到最大值、最小值等问题时,单调队列可以帮助我们高效地维护窗口内的元素,并在O(1)时间复杂度内获取窗口的最大值或最小值。
    • 其他题型也可用:计算窗口中元素的和、平均值;窗口的中位数、第k大元素
  • 单调栈:解决一些需要维护栈中元素的单调性的问题时非常有用,
    • 用途:找到每个元素左边或右边第一个比它大或小的元素等
  • 堆 (heapq):堆是一种特殊的树形数据结构(完全二叉树),常用于实现优先队列。在堆中,每个节点的值都大于等于/小于等于其子节点的值(最大堆/最小堆)。
    • heapq 模块默认小顶堆:注意,插入堆的元素可以是元组(2,obj),根据元组的第一个元素排序
      • heapify(iterable):将一个可迭代对象转换为堆,时间复杂度为 O(n)。
      • heappush(heap, item):向堆中插入一个元素。
      • heappop(heap):从堆中弹出并返回最小值(最小堆)或最大值(最大堆)。
      • heapreplace(heap, item):弹出并返回堆中的最小值或最大值,并将新元素插入堆中。
      • nlargest(n, iterable):返回可迭代对象中的前 n 个最大元素。
      • nsmallest(n, iterable):返回可迭代对象中的前 n 个最小元素。
    • 使用场景:与优先级有关的场景
      1. 优先队列:可以使用堆来维护元素的优先级,使得插入和删除操作的时间复杂度为 O(log n)
      2. 需要找到最大值或最小值的场景中,可以使用堆来快速获取最大/最小元素,时间复杂度为 O(1)
      3. 在一些排序算法中,堆排序就是基于堆的一种排序算法。
      4. 求中位数、滑动窗口中的最大值等:可以使用堆来辅助处理
      5. 合并多个有序列表:如果有多个有序列表,可以使用堆来合并这些列表,实现一个整体有序的列表。通过维护一个大小为 k 的堆,每次从堆中弹出最小元素,并将其对应列表的下一个元素插入堆中,直到所有列表遍历完毕。
      6. 将任务按照优先级加入堆中,然后依次执行优先级最高的任务
      7. 求解最小的 k 个数(用小顶堆):如果需要从一个很大的数据集中找到最小的 k 个数,可以使用堆来维护当前找到的最小的 k 个数。遍历数据集,将元素加入堆中,当堆的大小超过 k 时,弹出堆顶元素,保持堆中始终有 k 个最小元素
      8. 求解中位数:在动态数据流中,需要不断更新中位数时,可以使用两个堆来维护数据流的左半部分和右半部分,左半部分使用最大堆,右半部分使用最小堆,保持两个堆的大小差不超过 1。这样可以在 O(log n) 的时间复杂度内找到中位数
      9. 最小生成树算法:在最小生成树算法(如 Prim 算法、Kruskal 算法)中,可以使用堆来维护当前生成树与其他节点之间的最小边,从而高效地找到下一个要加入生成树的节点。

二叉树

  • 分类:满二叉树、完全二叉树、二叉树搜索数;平衡二叉搜索树
    • C++ 的mao/set/multimap,multiset的底层都是二叉树,unordered_map、unordered_set,unordered_map、unordered_set底层实现是哈希表
  • 存储方式:二叉树可以链式存储,也可以顺序存储(链表和数组存储,数组中用i, i2+1, i2+2)
  • 遍历方式:这两种遍历是图论中最基本的两种遍历方式
    • 深度优先遍历的递归法,可以用栈来实现;广度优先的递归法,用队列实现;
    • 深度优先遍历:先往深走,遇到叶子节点再往回走。
      • 前序遍历(递归法,迭代法):中左右
      • 中序遍历(递归法,迭代法):左中右
      • 后序遍历(递归法,迭代法):左右中
    • 广度优先遍历:一层一层的去遍历。
      • 层次遍历(迭代法)

二叉树递归写法的体系:三要素

  1. 确定递归函数的参数和返回值
  2. 确定终止条件:
  3. 确定单层递归的逻辑

二叉树迭代写法:用栈

  • 普通写法:
    • 前序:stack=[root],cur=stack.pop(),res.append(cur.val),stack.append(right),stack.append(left)
    • 中序:while stack or cur:while cur: stack.append(cur), cur = cur.left ; else:cur = stack.pop() , res.append(cur.val), cur = cur.right
    • 后序:前序改入账顺序,最后结果反转
  • 统一写法:
    • 在中节点入栈后,添加None标记,出栈遇到标记时,res.append(node.val)
if not root:
    return []
result = []
st = [root]

while st: # 出栈顺序就是最终顺序;下面是后序
    node = st.pop()
    if node != None:
        st.append(node) #中
        st.append(None)
        
        if node.right: #右
            st.append(node.right)
        if node.left: #左
            st.append(node.left)
    else:
        node = st.pop()
        result.append(node.val)

层序遍历可解决的问题:

  • 二叉树的最近公共祖先(Lowest Common Ancestor):在一个二叉树中找到两个节点的最近公共祖先。
  • 二叉树的最大深度和最小深度:计算二叉树的最大深度和最小深度。
  • 二叉树的层次遍历:按层级顺序遍历二叉树,常用队列实现。
  • 二叉树的镜像:将二叉树镜像翻转。
  • 二叉树的路径和:找到二叉树中路径和等于给定值的路径。

标签:遍历,元素,summary,链表,code,二叉树,数组,指针
From: https://www.cnblogs.com/kllkzl/p/18037486

相关文章

  • Codeforces 286E Ladies' Shop
    考虑\(p_i\)满足什么不会被选。令当前选出来的\(p_j\)的集合为\(S\)。能发现当用\(S\)中的数能够凑(可多选,可选重)出\(p_i\)时\(p_i\)就不会被选。考虑凑出\(p_i\)的最后一步所用的\(2\)个数\(x+y=p_i\)。因为这\(2\)个数一定能被\(S\)中的数凑出且题目......
  • esp32 VS Code环境搭建
    1清除旧的环境1.1删除已经安装过的espressidf残留环境1.2删除环境变量2安装Python环境https://www.python.org/downloads/需要注意将python添加至环境变量3安装ESP-IDF-tool离线包以管理员权限安装此工具包,且VSCode在安装过程中不要打开!!出现下列情况为安装成功......
  • Codeforces Round 909 (Div
    CodeforcesRound909(Div.3)A.GamewithIntegers显然就是还要不是三的倍数就能赢!intn; cin>>n; intk; while(n--) { cin>>k; if(k%3==0){ cout<<"Second"<<endl; }else{ cout<<"First"<<endl; } }B......
  • Codeforces Round 905 (Div
    CodeforcesRound905(Div.3)A.Morning此题将其看为光标一直移动,其中移动次数就是坐标之差的绝对值,0看做10,由于其显示也需一次操作,所以加上四。#include<bits/stdc++.h>usingnamespacestd;intmain(){ intt; cin>>t; while(t--) { intarr[4],count=0; ......
  • Codeforces Round 900 (Div
    CodeforcesRound900(Div.3)A.HowMuchDoesDaytonaCost?这个题简单,在子段上最常见的元素其实只要这个元素出现就行intt; cin>>t; intn,k; while(t--) { cin>>n>>k; intarr[n]; intout=0; for(inti=0;i<n;i++) { cin>>arr[i]; } for(......
  • Codeforces Round 888 (Div
    CodeforcesRound888(Div.3)A.EscalatorConversations推导即可,判断条件就是abs(h[i]-H)%k==0&&abs(h[i]-H)/k<m&&h[i]!=H,先要整除再能相隔abs(h[i]-H)/k个台阶谁高谁矮任意不影响,但是最后这个我就没注意到h[i]!=H小卡一会。#include<bits/stdc++.h>usingnamespacestd;......
  • Codeforces 1906L Palindromic Parentheses
    考虑先判定有无解对应的\(k\)的范围。首先若\(k=n\)一定无解,因为字符串开头是\(\texttt{(}\)结尾是\(\texttt{)}\)匹配不上。下界因为各有\(\frac{n}{2}\)个\(\texttt{()}\),所以可以先猜测下界就为\(\frac{n}{2}\)。考虑构造到这个下界。能发现只需要形如\(\te......
  • VSCode+Vim 开发
    VSCode+Vim开发一、安装及配置vim插件0.安装vim拓展1.拷贝配置到settings.json中settings.json在"文件"->"首选项"->"设置"->"文本编辑器"{"vim.easymotion":true,"vim.incsearch":true,"vim.useSystemCl......
  • Leetcode 53. 最大子数组和
    题目给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。输入输出样例输入:nums=[-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组[4,-1,2,1]的和最大,为6。输入:nums=[1]输出:1输入:nums......
  • Leetcode 76. 最小覆盖子串
    题目描述(难度hard)给你一个字符串S、一个字符串T,请在字符串S里面找出:包含T所有字母的最小子串。示例:输入:S="ADOBECODEBANC",T="ABC"输出:"BANC"说明:如果S中不存这样的子串,则返回空字符串""。如果S中存在这样的子串,我们保证它是唯一的答案。解题思路......