当前位置: 首页 > news >正文

菊厂笔试1

考点

题型

建议掌握内容

字符串

双指针、哈希、KMP

数组

前缀和、滑动窗口、二分查找、排序

栈与队列

单调栈、括号匹配、双端队列技巧

链表

快慢指针、翻转链表、合并链表

哈希表

判重、频次统计、哈希加滑窗技巧

二叉树

递归遍历、层序遍历、构造树

BFS、DFS、并查集、最短路(Dijkstra)

贪心

区间调度、背包类问题简化版

动态规划

背包问题、最长子序列/子数组

模拟题

比如“文件系统”、“装配线调度”

华为题目喜欢“工程场景模拟题”——既考算法又有业务背景。要熟练将题意转化为数据结构建模


✅ 二、笔试时的实战建议:

1. 分配时间:

  • 一般是 90 分钟 3 道题。

  • 第 1 题通常较简单(字符串/哈希/数组遍历),不要超过 15~20 分钟。

  • 第 2 题中等偏难,第 3 题较难(涉及DP/图),留足时间逐步完成。

2. 调试技巧:

  • 写自测样例,别只靠系统给的 case。

  • 提交前做边界值检查(空串、极大值、负数等)。

  • 注意输出格式,别因为“多了个空格”而 WA。

3. 善用函数封装、注释清晰:

class Solution:def maxSubArray(self, nums: List[int]) -> int:# 动态规划:f(i)表示以nums[i]结尾的最大子数组和pass


✅ 三、刷题技巧(目标清晰,练重点)

推荐平台:

  • LeetCode 热题 100 + Top Interview Questions

  • 牛客网 华为笔试真题专区

  • 力扣每日一题(用自己语言快速写)

刷题方法:

  • 反复刷而不是广度刷:做过的题二刷、三刷,尤其是你错过/不会的。

  • 总结题型套路,而不是每题从零开始。

  • 建议你建一个错题本/代码本子:写下你不会的点、易错的细节。


✅ 四、考前其他的基础准备

  • ✅ 一份简洁、清晰、无错误的 简历(PDF格式)

  • ✅ 简历中的项目尽量能答出:你做了什么、为什么这么做、遇到什么问题

  • ✅ 对华为业务线有一定了解,比如你投的是“云计算”、“终端”、“ICT”哪一块

代码风格转换

首先我们要从传统算竞中的 io 风代码转到工程上的面向对象封装风

什么是面向对象编程(OOP)?

将 数据&功能打包成一个对象,通过对其进行描述

什么是                可以理解为一种模版,比如猫类包含了所有猫的共同特征

什么是对象            从类而来的具体实例,比如一只叫“小豆泥”的暹罗猫就是猫类里面的一个对象

面向对象的三大特性

封装        将数据和方法放在一起,对外只暴露接口        class + def 组合,通过__init__构造

继承        子类拥有父类的属性和方法,代码复用            class B( A ) 表示B继承A

多态        不同对象同样的方法调用                                                

class Cat:                      # 定义一个类def __init__(self, name):   # 构造函数(初始化)self.name = namedef meow(self):             # 类的行为print(f"{self.name} 喵喵叫")douni = Cat("小豆泥")              # 创建一个对象
douni.meow()                    # 调用对象的方法 => 输出:咪咪 喵喵叫

在这个例子里面 meow 就是一个方法

self 指代的是实例自身,是面向对象编程中类方法的第一个参数,通过 self 可以访问对象的属性和其他方法

变化

一、结构上的改变

OI风格

面向对象风格

全部写在 main() 或直接写在全局

封装为 class Solution 中的方法

输入用 input()

输入由函数参数传入

输出用 print()

输出用 return 返回,由调用者决定是否打印

一般直接运行

用 if __name__ == "__main__": 测试调用

二、必须封装成函数

你不仅要用 return,还要把算法逻辑写成函数形式,这才符合面向对象的结构。

例如:

# 原始 OI 风格
a, b = map(int, input().split())
print(a + b)

转为面向对象 + 函数封装是:

class Solution:def add(self, a: int, b: int) -> int:return a + bif __name__ == "__main__":a, b = map(int, input().split())sol = Solution()print(sol.add(a, b))

三、输入不再写在函数内部,而是作为“参数”传入

这是最大区别之一:

  • OI风格:函数内直接 input()

  • OOP风格:函数内不写 input(),而是从参数接收数据

示例对比

OI 风格:

def solve():a, b = map(int, input().split())print(a + b)
solve()

面向对象风格:

class Solution:def add(self, a: int, b: int) -> int:return a + bif __name__ == "__main__":a, b = map(int, input().split())sol = Solution()print(sol.add(a, b))

小结:过渡时需要做的 3 件事

步骤

说明

1. 把主逻辑写成函数

用类封装为 def 函数(self, 参数)

2. 用 return 代替 print

函数输出用 return,主程序再决定是否 print

3. 输入变成参数传入

函数内部不要再 input(),由主程序读取传入

技巧

类中多个子函数封装逻辑,结构更清晰        

类型标注        def func(self , a : int ) -> int :        提高可读性

写完函数写主程序调用测试        if __name__=='__main__'       

比如gcd

class Solution:def gcd(self, a: int, b: int) -> int:# 辗转相除法while b != 0:a, b = b, a % breturn a# 本地测试用的主函数
if __name__ == "__main__":a,b=map(int,input().split())sol = Solution()                 # 创建类的实例result = sol.gcd(a,b)         # 调用函数print("最大公约数是:", result)    # 输出结果

OK,下面我们开始刷题

3.无重复字符的最长子串

我的第一个思路是set去重

但是很明显不行,因为他必须是子串

那么双指针滑动?

答案是可以的

我们需要维护四个变量:

l        各个字符上次位置

vis        当前窗口里面包含的字符

lmax        答案目标

lnow        当前窗口的长度


class Solution:'''def __init__:'''def lengest(self,s:str)->int:l={}vis=''lmax=0lnow=0for i in range(len(s)):if s[i] not in vis:vis+=s[i]lnow+=1l[s[i]]=ielse:#如果出现过:结算,更新lmax=max(lmax,lnow)last=l[s[i]]lnow=i-lastl[s[i]]=i#记得更新lvis=s[last+1:i+1]lmax=max(lmax,lnow)#最后一次清算return lmaxif __name__=='__main__':s=input()sol=Solution()  #先创建类对象res=sol.lengest(s)  #再通过对象调用方法print(res)

146.LRU缓存

146. LRU 缓存

很显然是字典

而且还需要一个变量存储最先进来的,方便后面逐出(队列)

可以直接用这个变量的长度来判断是否应该逐出

但还是用个变量存储吧,否则每次都要len()

而且注意题意“最久未使用”,那么不只是存储,读取、覆盖的话也得更新他的位置

更新的话先remove再append

from collections import deque
class LRUCache:def __init__(self,capacity:int):self.lmax=capacityself.lnow=0#self.last=0self.deque=deque()self.d={}#defaultdict(int)def get(self,key:int)->int:if key in self.d:self.deque.remove(key)self.deque.append(key)return self.d[key]else:return -1def put(self,key:int,value:int)->None:if self.lnow<self.lmax:#未形成窗口#低级错误:竟然先放进去了self.d[key]=valueif key not in self.d:self.d[key]=valueself.deque.append(key)self.lnow+=1else:               #"最久未使用“self.d[key]=valueself.deque.remove(key)#用remove删除后重新加self.deque.append(key)else:#形成窗口if key in self.d:self.d[key]=valueself.deque.remove(key)#用remove删除后重新加self.deque.append(key)self.deque.append(key)else:s=self.deque.popleft()del self.d[s]   #self.deque.append(key)self.d[key]=value        

不难发现其实每次输入key“使用”都得更新他的地位 

但是这样只有5%用时击败和80%用存击败

正确的做法是用 OrderedDict

OrderedDict 是 Python collections 模块中的一个 有序字典,它和普通 dict 基本功能相同,但能记住键的插入顺序(或访问顺序)

导入

from collections import OrderedDict

主要特性

特性

说明

保留顺序

记录元素插入的顺序(或访问顺序)

支持 move_to_end(key)

可以将某个键移动到字典的开头或末尾

支持 popitem()

可以按顺序弹出最前面或最后面的元素

兼容 dict

用法和普通字典几乎一致

常用方法举例

1. 插入顺序保留

from collections import OrderedDictod = OrderedDict()
od['a'] = 1
od['b'] = 2
od['c'] = 3print(od)  # 输出:OrderedDict([('a', 1), ('b', 2), ('c', 3)])

2. move_to_end(key, last=True)

  • 默认 last=True:将键移动到末尾(表示最近使用)

  • last=False:将键移到开头

od.move_to_end('a')          # 'a' 移到最后
od.move_to_end('b', last=False)  # 'b' 移到最前

3. popitem(last=True)

  • last=True(默认):弹出最后一个键值对(表示最近使用)

  • last=False:弹出最前的键值对(表示最久未使用)

od.popitem()          # 弹出最后一个
od.popitem(last=False)  # 弹出第一个

因此我们可以用:

  • move_to_end(key)        在使用时将更新其地位

  • popitem(last=False)      “删除不是last最新的”从左边删除最久未使用的项;

  • OrderedDict 本身就是 O(1) 操作,配合 dict 的查找速度,非常高效。

class LRUCache:def __init__(self, capacity: int):self.cache = OrderedDict()self.capacity = capacitydef get(self, key: int) -> int:if key not in self.cache:return -1# 把访问的 key 提到最前(代表最近访问)self.cache.move_to_end(key)return self.cache[key]def put(self, key: int, value: int) -> None:if key in self.cache:# 更新值并将其移到末尾self.cache.move_to_end(key)self.cache[key] = valueif len(self.cache) > self.capacity:# 弹出最旧的项(先进的)self.cache.popitem(last=False)

5.最长回文子串 

经典马拉车Malacher 

class Solution:def longestPalindrome(self, s: str) -> str:t='#'+'#'.join(s)+'#'n=len(t)p=[0]*nC=R=maxlen=center=0for i in range(n):p[i]=min(p[2*C-i],R-i) if R-i>0 else 0while i+p[i]+1<n and i-p[i]-1>=0\and  t[i+p[i]+1]==t[i-p[i]-1]:p[i]+=1if i+p[i]>R:C,R=i,i+p[i]if p[i]>maxlen:maxlen,center=p[i],ireturn s[(center-maxlen)//2:(center+maxlen)//2]

我明天写一章讲讲马拉车,今天先休息了

相关文章:

  • 电子电器架构 --- 电气/电子架构如何发展以满足其处理和传感器融合需求
  • CAN总线通讯接口卡:工业通信的核心桥梁
  • 在UI原型设计中,低、高保真原型图有什么区别?
  • 验证码(笔记)
  • web 自动化之 Selenium 元素定位和浏览器操作
  • 数据结构 - 10( B- 树 B+ 树 B* 树 4000 字详解 )
  • Node.js 技术原理分析系列9——Node.js addon一文通
  • AI开发跃迁指南(第三章:第四维度1——Milvus、weaviate、redis等向量数据库介绍及对比选型)
  • 腾讯云:数字世界的“量子熔炉”与硅基文明引擎​
  • LeetCode 热题 100 238. 除自身以外数组的乘积
  • 16011.自动分簇KMeans算法
  • element MessageBox 实现底部三个按钮或者更多按钮—开箱即用
  • 【MySQL】第二弹——MySQL表的增删改查(CURD))
  • 【MySQL】存储引擎 - MEMORY详解
  • 使用 CDN 在国内加载本地 PDF 文件并处理批注:PDF.js 5.x 实战指南
  • Ubuntu 安装 Nginx
  • 【hadoop】案例:Sqoop迁移仓库数据
  • OpenTelemetry 介绍
  • 【软件推荐——ScreenToGif】
  • docker 部署clickhouse
  • 保证断电、碰撞等事故中车门系统能够开启!汽车车门把手将迎来强制性国家标准
  • 李公明︱一周书记:浪漫主义为什么……仍然重要?
  • 全国首例在沪完成,这项近视治疗手术不到10秒
  • 秦洪看盘|受阻回落,蓄积新做多能量
  • 印媒证实:至少3架印军战机7日在印控克什米尔地区坠毁
  • 中演协:五一假期全国营业性演出票房收入同比增长3.6%