问题

非计算机专业,想刷leetcode,请问在此之前需要做什么准备?

回答
你好!很高兴你对刷 LeetCode 感兴趣。作为一个非计算机专业的朋友,迈出这一步是非常棒的!别担心,这绝对是一个可以攻克的挑战,而且这个过程本身也会让你收获很多。

在你开始“刷题”这个行动之前,有几个关键的准备工作,它们能让你事半功倍,避免一开始就碰得头破血流,对编程产生畏惧感。我来给你详细说说,尽量接地气一点,就当是咱们朋友之间聊聊:

第一步:建立对编程最基础的认知和工具链

很多人一听到“刷题”,就觉得得马上会写代码。其实不然,我们先要对“代码”和“编程”有个大致的概念,知道它们是怎么一回事。

1. 了解编程是怎么回事:
别把它想得太神秘。 编程就是你跟电脑说话的一种方式。我们用一种它能理解的语言(编程语言)来告诉它,一步一步地做什么事情。
举个例子: 就像你让朋友帮忙买东西,你会说“去超市,买一瓶牛奶,回来给我。” 编程也是这样,你告诉电脑“开始一个变量叫做 `count`,初始值是0;循环10次;每次让 `count` 增加1;循环结束,打印 `count` 的值。”
看点什么? 你可以找一些非常非常入门级的视频,比如“编程是什么”、“计算机是如何工作的”这种视频。不用看那种教你写具体代码的,就是了解一下大概概念。B站上有很多这类科普视频,搜一下就能找到。

2. 选择一门“入门友好”的编程语言:
为什么要有“入门友好”的? LeetCode 支持多种语言,但有些语言语法复杂、或者学习曲线陡峭,一开始就用它们可能会让你卡在语法上,而不是思考算法。
推荐 Python: 理由如下:
语法简洁易懂: 它的语法非常接近英语,读起来就像伪代码一样,容易理解。很多时候你写出来的代码,别人一看就能猜到你想干嘛。
生态丰富,社区活跃: 遇到问题很容易搜到答案,而且有很多好用的库可以直接拿来用,不用自己从头造轮子。
在数据科学、机器学习领域应用广泛: 这是未来很多公司会用到的技术,学了它也算顺带的技能投资。
其他选择(但对新手可能稍微有门槛):
Java: 企业级开发常用,但语法比较严谨,需要写更多东西。
C++: 运行效率高,很多竞赛和底层开发用,但语法相对复杂。
我的建议: 就选 Python! 别纠结,先学起来。等你掌握了用 Python 思维来解决问题,将来想换别的语言也不是难事。

3. 搭建你的编程环境:
你需要一个地方来写代码和运行它。
Python 环境:
安装 Python: 去 Python 官网(python.org)下载最新版的 Python,直接安装即可。过程中记得勾选“Add Python to PATH”选项(如果找不到,安装完再搜索一下如何配置)。
代码编辑器/IDE:
VS Code (Visual Studio Code): 这个强烈推荐!它免费、强大、插件多,而且对 Python 支持非常好。你只需要在 VS Code 里安装一个 Python 插件就可以了。
PyCharm (Community Edition): 这是专门为 Python 开发的 IDE,功能非常全面,也非常适合初学者。免费的社区版足够用了。
在线编程环境: 如果你不想在本地安装,LeetCode 网站本身就提供在线编辑器,可以直接在浏览器里写代码跑,非常方便。刚开始的话,可以用 LeetCode 网站的编辑器熟悉一下即可。

第二步:学习编程语言的基础知识( Python 为例)

现在我们有了方向和工具,就可以开始学习这门语言最基本的东西了。这部分是 重中之重,决定了你之后刷题能否顺畅。

1. 基本语法和概念:
变量和数据类型: 数字 (int, float), 字符串 (str), 布尔值 (bool)。
数据结构:
列表 (list): 就像一个可以放很多东西的袋子,可以往里加、删、改,并且顺序固定。
元组 (tuple): 类似列表,但一旦创建就不能修改。
字典 (dict): 就像一个电话簿,用名字(键)来查找对应的号码(值)。
集合 (set): 一堆不重复的元素组成的无序集合。
控制流:
条件语句: `if`, `elif`, `else` (如果...否则如果...否则...)。
循环语句: `for` (遍历), `while` (当条件满足时重复)。
函数: 把一段可以重复使用的代码打包起来,起个名字,以后可以直接调用。
面向对象编程 (OOP) 的基础: 类 (class), 对象 (object), 方法 (method)。这个不用一开始就深入,了解一下概念即可。

2. 学习资源推荐:
官方文档: Python 官网有非常详细的文档,但对新手可能有点枯燥。
在线教程/课程:
菜鸟教程 (runoob.com): 这个网站很多初学者都用,内容很全,例子也比较多。
廖雪峰的 Python 教程: 很多国内学习者都推荐,讲解清晰易懂。
Codecademy, freeCodeCamp: 这两个是国外的免费交互式学习平台,你可以在网页上边学边练。
B站上的 Python 入门视频: 搜索“Python入门教程”,选择评价高、更新日期近的博主。
最重要的: 边学边练! 看到一个概念,立刻在你的编辑器里敲代码跑一下,看看效果。不要只看不练。

第三步:了解算法和数据结构的基础概念(但不是深入学习)

在你开始刷 LeetCode 的题目之前,你需要对一些最基本、最常用的算法和数据结构有个模糊的印象。不是要求你精通,而是知道它们是什么,以及为什么会用到。

1. 你需要了解的几个核心概念:
时间复杂度和空间复杂度 (Big O Notation): 这是衡量算法效率的极其重要的标准。简单说,就是算法运行需要多少时间(时间复杂度)和多少内存(空间复杂度),并且这些消耗会随着输入规模的增大而如何增长。LeetCode 上的很多题目都会考察这个。
可以搜搜看: “时间复杂度 O(n) 是什么意思”,“算法复杂度图解”。
常见数据结构:
数组 (Array): 可以通过索引直接访问元素的结构。
链表 (Linked List): 每个元素都指向下一个元素,插入和删除比较方便。
栈 (Stack): 后进先出 (LIFO),就像叠盘子。
队列 (Queue): 先进先出 (FIFO),就像排队买票。
哈希表 (Hash Table) / 字典 (Dictionary): 通过键快速查找值。
树 (Tree): 比如二叉树,常用于表示层级关系,二分搜索树在查找时效率很高。
图 (Graph): 节点和边构成的网络,用于表示关系。
常见算法:
排序算法: 冒泡排序、选择排序、插入排序、快速排序、归并排序。 (了解思想就行,不用会写)
搜索算法: 线性查找、二分查找。
递归 (Recursion): 函数调用自身,解决问题的一种思路。

2. 学习资源推荐(这个阶段):
视频讲解: 很多博主会用动画或图解的方式来解释这些概念,会更容易理解。搜索“数据结构与算法入门”、“二分查找原理”、“链表概念讲解”等等。
图解算法系列: 网上有很多“图解XX算法”的文章或视频,非常直观。

第四步:了解 LeetCode 平台的使用

在你准备好了以上的基础之后,就可以开始接触 LeetCode 这个平台了。

1. 注册账号并熟悉界面:
注册 LeetCode 账号。
浏览首页,看看题目列表、已解决问题、题解区等。
找到语言设置,将其改为你选择的 Python。

2. 如何开始做题:
从“简单 (Easy)”难度开始: 千万不要一开始就挑战困难题目! 从标记为 Easy 的题目开始,它们通常是用来巩固你基础知识的。
阅读题目: 仔细阅读题目描述,理解它要求你做什么。注意输入输出格式、边界条件等细节。
思考解题思路: 这是最关键的一步。不要急着看答案。尝试自己想办法,哪怕是最笨的办法。
举个例子: 如果题目是“给一个数组,找出和为某个目标值的两个数”,你可以先想:我能不能第一个数拿出来,然后检查后面所有的数,看有没有一个能凑成目标值的?
将思路转化为代码: 用你熟悉的编程语言(Python)把你的思路写成代码。
测试你的代码: LeetCode 会提供一些测试用例,运行你的代码,看看能否通过。如果不行,就 Debug(调试)。
查看题解和讨论: 如果实在想不出来,或者代码虽然对了但效率不高,可以去看看别人的题解和讨论。学习别人是如何思考和优化代码的。重点是学习思路和技巧,而不是照抄代码。
理解时间/空间复杂度: 看看别人写的代码,思考一下它的时间复杂度是多少,空间复杂度又是多少。

一些额外的建议,让你走得更稳:

耐心是关键: 非计算机专业的学习需要时间,不要期望一蹴而就。遇到挫折是正常的,关键是坚持下去。
循序渐进: 不要贪多求快。把一个知识点弄懂了,再学下一个。
理解而非记忆: 目标是理解算法背后的逻辑和思想,而不是死记硬背代码。
多动手实践: 编程是实践的学科,看再多不如自己写一遍。
不要害怕犯错: 错误是学习过程中最好的老师。每次的错误都是一次宝贵的经验。
保持好奇心: 在学习过程中,如果遇到某个函数、某个语法不太明白,不妨深入查一下,你会发现很多有趣的知识。
找个学习伙伴(可选): 如果能找到志同道合的朋友一起学习,互相鼓励、交流问题,效果会更好。

总结一下你现在需要做的准备:

1. 初步了解编程是什么。
2. 决定使用 Python 语言。
3. 搭建好 Python 的开发环境(或者准备好使用 LeetCode 官网的在线编辑器)。
4. 学习 Python 的基础语法和常用数据结构。
5. 对算法和数据结构(如时间复杂度、常见数据结构、简单算法思想)有个初步的印象。

当你完成了这些基础的准备,你就可以自信地踏上 LeetCode 的征程了!过程可能会有点挑战,但相信我,当你解决了一个难题,那种成就感是无与伦比的。祝你刷题愉快,学习顺利!如果过程中有任何问题,随时可以再来问我。

网友意见

user avatar

什么准备都别做,直接开始刷吧。从easy开始。

对于每道题:

  1. 自己做做看。
  2. 做不出就看官方代码。
  3. 代码看不懂就看各种题解(如果是语言基础不够,看不懂C/C++的某个函数,建议下载个IDE单步调试)。
  4. 题解看不懂就照着题解里的关键字搜索,哪句看不懂就看哪句,再就是加个力扣官方微信群在里面问。或者在题解下面评论区问。
user avatar

我从2sum不会写,到通过狗家和脸家实习的电面。走了很多弯路。现在回过头来看,埋头猛刷(LeetCode),其实不一定是最有效的方式。尤其是Google,面试过程中,特别强调交流。所以我们平时刷题就需要安装四个步骤来要求自己。

第一是communication。一定要和考官交流思路,还有就是不明白的地方一定要问清楚。

第二是problem solving,要展示自己的解决问题的策略。比如选数据结构什么的,一定要讲明白为什么要用各种算法和数据结构。

第三是coding。在前面两步的基础上,写出来干净正确的代码。

第四是testing,一定要回去验证自己的代码。这个过程中可以分析一下代码的复杂度。

怎么去练以上的步骤,有详细过程解析的入门教程就能起到很重要的作用。我在刷题的中期,在某论坛的推荐下,接触到了educative的课程。特别有帮助。

这些课程是我在准备算法面试时,自己跟着学完且颇有成效的。作为转码的选手,这些课程帮我梳理了主要考察的内容,更让我有了系统性的知识框架。

这些课程主要还是适用于美国的面试环境,咱们平时刷题的时候不太注重英文交流方面的训练,这样在面试的时候哪怕会做题,但不能让面试官知晓意图,面试结果也不会突出的。

所以平时不仅仅要能写出来代码,还得能用英语表达清楚每一步的意义。这些英文课程的表述能让大家早点习惯各种术语的表达。

之前这些课程都是买断的,现在也只能一年之内有效了。单独购买这些课程可以,但其实还是推荐直接按年来学,一年之内把下面这些课程学完是没有问题的。

如果有需要的小伙伴,这个网站的课程,能用ZHIHUEDU-10的coupon code来享受按年或是按月收费模式的额外九折的优惠。

我现在大概介绍一下我用过的几门课:

Grokking Dynamic Programming Patterns for Coding Interviews. 这门课主要是针对DP,大部分的题都用递归,Top-Down, Bottom up三种方法解一遍,来龙去脉讲得非常清楚。特别适合DP有一定感觉,但又不能融汇贯通的小伙伴。

Data Structures in Java: An Interview Refresher.这一门课是把数据结构里面的基础数据结构都用java实现了一遍,对于用java的同学特别有帮助,java的基础在刷题的过程中,还是要必须掌握的。从复杂度开始,Arrays,LinkedLists, Stacks/Queues, Graphs, Trees, Trie, Heaps, Hash Tables,全都实现了一遍。而且还有配套的基础LeetCode题。是一个入门的很棒的教程。

Coderust: Hacking the Coding Interview.这门课精选了八十左右道题,每道题都有详细的讲解,对我最有帮助的地方是里面的代码运行步骤,特别详细,对代码的理解特别有帮助。

Grokking the Coding Interview: Patterns for Coding Questions.这门课程是一个总结提高的课程,它把算法面试的遇到的题型分成了各种模式,每类题各个击破。比如最经典的sliding window模式,Two pointers模式,快慢指针模式,合并intervals模式,cyclic sort模式,in-place翻转链表模式,树上的BFS,树上的DFS,双Heaps模式,subsets模式,二分法变种,Top K模式,多路模式(K-ways),0/1背包,拓扑排序。

Grokking the Machine Learning Interview 对机器学习面试的内容做出了详细的梳理,对大家准备机器学习的面试以及team match有很大的帮助。

对于刚刷题的小伙伴来说,很多题目就是一个很抽象的描述,刷了几百道题,还是不知道为啥要刷这些题,也不能很好的放到实际的生产生活环境中。针对上面这些知识和场景之间的gap,educative推出了下面的这一系列课程,希望能帮助大家从实际生产环境的角度去解答算法问题。

下面这个系列是新出的课程:通过大公司真实常见问题来破解算法面试。

下面是用Java语言的:

还提供了Python:

C++:

以及JS版本:


当然还有一名最出名的:Grokking the System Design Interview.鼎鼎大名的system design课程。

以及OOD课程,Amazon面试喜欢考察OOD的内容。



其他还有很多课程可以选择,可以去搜索


刷题之前,了解一下基本的数据结构,然后了解一下都有哪些常见的题目类型。刷的时候第一二遍最好按照类型来刷,这都是过来人的经验了。

关于题目类型的回答,大家可以看看这个回答。刷之前先过上一下总会有收获的。

刷题要坚持,加油!

搬运过来方便大家阅读:

这个课程来自于educative,是一个美国的算法面试方面很出色的网课平台。

这门课程是一个算法总结提高的课程,它把算法面试中可能遇到的题分成了各种模式,每类题各个击破。

如果想买订阅Subscriptions)的小伙伴,则可以用ZHIHUEDU-10(必须一模一样输入)的coupon code来获取额外九的优惠按年和按月均适用


下面这个系列是新出的课程:通过大公司真实场景问题来破解算法面试。

下面是用Java语言的:

还提供了Python:

C++:

以及JS版本:



比如有最经典的sliding window模式,Two pointers模式,快慢指针模式,合并intervals模式,cyclic sort模式,in-place翻转链表模式,树上的BFS,树上的DFS,双Heaps模式,subsets模式,二分法变种,Top K模式,多路模式(K-ways),0/1背包,拓扑排序。

需要的小伙伴就去来一波吧!

他家最最出名的还是这门Grokking the System Design Interview, 但凡提到准备系统设计,这门课都上入门必推的:

以及OOD: Grokking the Object Oriented Design Interview

这门机器学习面试指南是这个系列最新的课程:

目前市面上机器学习面试相关的课程比较少,这门课程应该非常值得!


方便大家阅读,我把内容也贴出来放在这个回答下:

1. Pattern: Sliding window,滑动窗口类型

滑动窗口类型的题目经常是用来执行数组或是链表上某个区间(窗口)上的操作。比如找最长的全为1的子数组长度。滑动窗口一般从第一个元素开始,一直往右边一个一个元素挪动。当然了,根据题目要求,我们可能有固定窗口大小的情况,也有窗口的大小变化的情况。


下面是一些我们用来判断我们可能需要上滑动窗口策略的方法

  • 这个问题的输入是一些线性结构:比如链表呀,数组啊,字符串啊之类的
  • 让你去求最长/最短子字符串或是某些特定的长度要求

经典题目:

Maximum Sum Subarray of Size K (easy)

Smallest Subarray with a given sum (easy)

Longest Substring with K Distinct Characters (medium)

Fruits into Baskets (medium)

No-repeat Substring (hard)

Longest Substring with Same Letters after Replacement (hard)

Longest Subarray with Ones after Replacement (hard)


2. Pattern: two points, 双指针类型

双指针是这样的模式:两个指针朝着左右方向移动(双指针分为同向双指针和异向双指针),直到他们有一个或是两个都满足某种条件。双指针通常用在排好序的数组或是链表中寻找对子。比如,你需要去比较数组中每个元素和其他元素的关系时,你就需要用到双指针了。

我们需要双指针的原因是:如果你只用一个指针的话,你得来回跑才能在数组中找到你需要的答案。这一个指针来来回回的过程就很耗时和浪费空间了 — 这是考虑算法的复杂度分析的时候的重要概念。虽然brute force一个指针的解法可能会奏效,但时间复杂度一般会是O(n²)。在很多情况下,双指针能帮助我们找到空间或是时间复杂度更低的解。


识别使用双指针的招数:

  • 一般来说,数组或是链表是排好序的,你得在里头找一些组合满足某种限制条件
  • 这种组合可能是一对数,三个数,或是一个子数组

经典题目:

Pair with Target Sum (easy)

Remove Duplicates (easy)

Squaring a Sorted Array (easy)

Triplet Sum to Zero (medium)

Triplet Sum Close to Target (medium)

Triplets with Smaller Sum (medium)

Subarrays with Product Less than a Target (medium)

Dutch National Flag Problem (medium)


3. Pattern: Fast & Slow pointers, 快慢指针类型

这种模式,有一个非常出门的名字,叫龟兔赛跑。咱们肯定都知道龟兔赛跑啦。但还是再解释一下快慢指针:这种算法的两个指针的在数组上(或是链表上,序列上)的移动速度不一样。还别说,这种方法在解决有环的链表和数组时特别有用

通过控制指针不同的移动速度(比如在环形链表上),这种算法证明了他们肯定会相遇的。快的一个指针肯定会追上慢的一个(可以想象成跑道上面跑得快的人套圈跑得慢的人)。


咋知道需要用快慢指针模式勒?

  • 问题需要处理环上的问题,比如环形链表和环形数组
  • 当你需要知道链表的长度或是某个特别位置的信息的时候

那啥时候用快慢指针而不是上面的双指针呢?

  • 有些情形下,咱们不应该用双指针,比如我们在单链表上不能往回移动的时候。一个典型的需要用到快慢指针的模式的是当你需要去判断一个链表是否是回文的时候。

经典题目:

LinkedList Cycle (easy)

Start of LinkedList Cycle (medium)

Happy Number (medium)

Middle of the LinkedList (easy)


4. Pattern: Merge Intervals,区间合并类型

区间合并模式是一个用来处理有区间重叠的很高效的技术。在设计到区间的很多问题中,通常咱们需要要么判断是否有重叠,要么合并区间,如果他们重叠的话。这个模式是这么起作用的:

给两个区间,一个是a,另外一个是b。别小看就两个区间,他们之间的关系能跑出来6种情况。详细的就看图啦。


理解和识别这六种情况,灰常重要。因为这能帮你解决一大堆问题。这些问题从插入区间到优化区间合并都有。

怎么识别啥时候用合并区间模式呀?

  • 当你需要产生一堆相互之间没有交集的区间的时候
  • 当你听到重叠区间的时候

经典题目:

Merge Intervals (medium)

Insert Interval (medium)

Intervals Intersection (medium)

Conflicting Appointments (medium)


5. Pattern: Cyclic Sort,循环排序

这种模式讲述的是一直很好玩的方法:可以用来处理数组中的数值限定在一定的区间的问题。这种模式一个个遍历数组中的元素,如果当前这个数它不在其应该在的位置的话,咱们就把它和它应该在的那个位置上的数交换一下。你可以尝试将该数放到其正确的位置上,但这复杂度就会是O(n^2)。这样的话,可能就不是最优解了。因此循环排序的优势就体现出来了。

咋鉴别这种模式?

  • 这些问题一般设计到排序好的数组,而且数值一般满足于一定的区间
  • 如果问题让你需要在排好序/翻转过的数组中,寻找丢失的/重复的/最小的元素


经典题目:

Cyclic Sort (easy)

Find the Missing Number (easy)

Find all Missing Numbers (easy)

Find the Duplicate Number (easy)

Find all Duplicate Numbers (easy)

6. Pattern: In-place Reversal of a LinkedList,链表翻转


在众多问题中,题目可能需要你去翻转链表中某一段的节点。通常,要求都是你得原地翻转,就是重复使用这些已经建好的节点,而不使用额外的空间。这个时候,原地翻转模式就要发挥威力了。

这种模式每次就翻转一个节点。一般需要用到多个变量,一个变量指向头结点(下图中的current),另外一个(previous)则指向咱们刚刚处理完的那个节点。在这种固定步长的方式下,你需要先将当前节点(current)指向前一个节点(previous),再移动到下一个。同时,你需要将previous总是更新到你刚刚新鲜处理完的节点,以保证正确性。

咱们怎么去甄别这种模式呢?

  • 如果你被问到需要去翻转链表,要求不能使用额外空间的时候

经典题目:

Reverse a LinkedList (easy)

Reverse a Sub-list (medium)

Reverse every K-element Sub-list (medium)


7. Pattern: Tree Breadth First Search,树上的BFS

这种模式基于宽搜(Breadth First Search (BFS)),适用于需要遍历一颗树。借助于队列数据结构,从而能保证树的节点按照他们的层数打印出来。打印完当前层所有元素,才能执行到下一层。所有这种需要遍历树且需要一层一层遍历的问题,都能用这种模式高效解决。

这种树上的BFS模式是通过把根节点加到队列中,然后不断遍历直到队列为空。每一次循环中,我们都会把队头结点拿出来(remove),然后对其进行必要的操作。在删除每个节点的同时,其孩子节点,都会被加到队列中。

识别树上的BFS模式:

  • 如果你被问到去遍历树,需要按层操作的方式(也称作层序遍历)

经典题目:

Binary Tree Level Order Traversal (easy)

Reverse Level Order Traversal (easy)

Zigzag Traversal (medium)

Level Averages in a Binary Tree (easy)

Minimum Depth of a Binary Tree (easy)

Level Order Successor (easy)

Connect Level Order Siblings (medium)


8. Pattern: Tree Depth First Search,树上的DFS

树形DFS基于深搜(Depth First Search (DFS))技术来实现树的遍历。

咱们可以用递归(或是显示栈,如果你想用迭代方式的话)来记录遍历过程中访问过的父节点。

该模式的运行方式是从根节点开始,如果该节点不是叶子节点,我们需要干三件事:

  1. 需要区别我们是先处理根节点(pre-order,前序),处理孩子节点之间处理根节点(in-order,中序),还是处理完所有孩子再处理根节点(post-order,后序)。
  2. 递归处理当前节点的左右孩子。

识别树形DFS:

  • 你需要按前中后序的DFS方式遍历树
  • 如果该问题的解一般离叶子节点比较近。

经典题目:

Binary Tree Path Sum (easy)

All Paths for a Sum (medium)

Sum of Path Numbers (medium)

Path With Given Sequence (medium)

Count Paths for a Sum (medium)


9. Pattern: Two Heaps,双堆类型

很多问题中,我们被告知,我们拿到一大把可以分成两队的数字。为了解决这个问题,我们感兴趣的是,怎么把数字分成两半?使得:小的数字都放在一起,大的放在另外一半。双堆模式就能高效解决此类问题。

正如名字所示,该模式用到了两个堆,是不是很难猜?一个最小堆用来找最小元素;一个最大堆,拿到最大元素。这种模式将一半的元素放在最大堆中,这样你可以从这一堆中秒找到最大元素。同理,把剩下一半丢到最小堆中,O(1)时间找到他们中的最小元素。通过这样的方式,这一大堆元素的中位数就可以从两个堆的堆顶拿到数字,从而计算出来。

判断双堆模式的秘诀:

  • 这种模式在优先队列,计划安排问题(Scheduling)中有奇效
  • 如果问题让你找一组数中的最大/最小/中位数
  • 有时候,这种模式在涉及到二叉树数据结构时也特别有用

经典题目:

Find the Median of a Number Stream (medium)

Sliding Window Median (hard)

Maximize Capital (hard)


10. Pattern: Subsets,子集类型,一般都是使用多重DFS

超级多的编程面试问题都会涉及到排列和组合问题。子集问题模式讲的是用BFS来处理这些问题。

这个模式是这样的:

给一组数字 [1, 5, 3]

  1. 我们从空集开始:[[]]
  2. 把第一个数(1),加到之前已经存在的集合中:[[], [1]];
  3. 把第二个数(5),加到之前的集合中得到:[[], [1], [5], [1,5]];
  4. 再加第三个数(3),则有:[[], [1], [5], [1,5], [3], [1,3], [5,3], [1,5,3]].

该模式的详细步骤如下:

如果判断这种子集模式:

  • 问题需要咱们去找数字的组合或是排列

经典题目:

Subsets (easy)

Subsets With Duplicates (easy)

Permutations (medium)

String Permutations by changing case (medium)

Balanced Parentheses (hard)

Unique Generalized Abbreviations (hard)


11. Pattern: Modified Binary Search,改造过的二分

当你需要解决的问题的输入是排好序的数组,链表,或是排好序的矩阵,要求咱们寻找某些特定元素。这个时候的不二选择就是二分搜索。这种模式是一种超级牛的用二分来解决问题的方式。

对于一组满足上升排列的数集来说,这种模式的步骤是这样的:

  1. 首先,算出左右端点的中点。最简单的方式是这样的:middle = (start + end) / 2。但这种计算方式有不小的概率会出现整数越界。因此一般都推荐另外这种写法:middle = start + (end — start) / 2
  2. 如果要找的目标改好和中点所在的数值相等,我们返回中点的下标就行
  3. 如果目标不等的话:我们就有两种移动方式了
  4. 如果目标比中点在的值小(key < arr[middle]):将下一步搜索空间放到左边(end = middle - 1)
  5. 如果比中点的值大,则继续在右边搜索,丢弃左边:left = middle + 1

图示该过程的话,如下图所示:

经典题目:

Order-agnostic Binary Search (easy)

Ceiling of a Number (medium)

Next Letter (medium)

Number Range (medium)

Search in a Sorted Infinite Array (medium)

Minimum Difference Element (medium)

Bitonic Array Maximum (easy)


12. Pattern: Top ‘K’ Elements,前K个系列

任何让我们求解最大/最小/最频繁的K个元素的题,都遵循这种模式。

用来记录这种前K类型的最佳数据结构就是堆了(译者注:在Java中,改了个名,叫优先队列(PriorityQueue))。这种模式借助堆来解决很多这种前K个数值的问题。

这个模式是这样的:

  1. 根据题目要求,将K个元素插入到最小堆或是最大堆。
  2. 遍历剩下的还没访问的元素,如果当前出来到的这个元素比堆顶元素大,那咱们把堆顶元素先删除,再加当前元素进去。

注意这种模式下,咱们不需要去排序数组,因为堆具有这种良好的局部有序性,这对咱们需要解决问题就够了。

识别最大K个元素模式:

  • 如果你需要求最大/最小/最频繁的前K个元素
  • 如果你需要通过排序去找一个特定的数

经典题目:

Top ‘K’ Numbers (easy)

Kth Smallest Number (easy)

‘K’ Closest Points to the Origin (easy)

Connect Ropes (easy)

Top ‘K’ Frequent Numbers (medium)

Frequency Sort (medium)

Kth Largest Number in a Stream (medium)

‘K’ Closest Numbers (medium)

Maximum Distinct Elements (medium)

Sum of Elements (medium)

Rearrange String (hard)


13. Pattern: K-way merge,多路归并

K路归并能帮咱们解决那些涉及到多组排好序的数组的问题。

每当你的输入是K个排好序的数组,你就可以用堆来高效顺序遍历其中所有数组的所有元素。你可以将每个数组中最小的一个元素加入到最小堆中,从而得到全局最小值。当我们拿到这个全局最小值之后,再从该元素所在的数组里取出其后面紧挨着的元素,加入堆。如此往复直到处理完所有的元素。

该模式是这样的运行的:

  1. 把每个数组中的第一个元素都加入最小堆中
  2. 取出堆顶元素(全局最小),将该元素放入排好序的结果集合里面
  3. 将刚取出的元素所在的数组里面的下一个元素加入堆
  4. 重复步骤2,3,直到处理完所有数字

识别K路归并:

  • 该问题的输入是排好序的数组,链表或是矩阵
  • 如果问题让咱们合并多个排好序的集合,或是需要找这些集合中最小的元素

经典题目:

Merge K Sorted Lists (medium)

Kth Smallest Number in M Sorted Lists (Medium)

Kth Smallest Number in a Sorted Matrix (Hard)

Smallest Number Range (Hard)


14. Pattern: 0/1 Knapsack (Dynamic Programming),0/1背包类型


经典题目:

0/1 Knapsack (medium)

Equal Subset Sum Partition (medium)

Subset Sum (medium)

Minimum Subset Sum Difference (hard)


15. Pattern: Topological Sort (Graph),拓扑排序类型

拓扑排序模式用来寻找一种线性的顺序,这些元素之间具有依懒性。比如,如果事件B依赖于事件A,那A在拓扑排序顺序中排在B的前面。

这种模式定义了一种简单方式来理解拓扑排序这种技术。

这种模式是这样奏效的:

  1. 初始化
    a) 借助于HashMap将图保存成邻接表形式。
    b) 找到所有的起点,用HashMap来帮助记录每个节点的入度
  2. 创建图,找到每个节点的入度
    a) 利用输入,把图建好,然后遍历一下图,将入度信息记录在HashMap中
  3. 找所有的起点
    a) 所有入度为0的节点,都是有效的起点,而且我们讲他们都加入到一个队列中
  4. 排序
    a) 对每个起点,执行以下步骤
    —i) 把它加到结果的顺序中
    — ii)将其在图中的孩子节点取到
    — iii)将其孩子的入度减少1
    — iv)如果孩子的入度变为0,则改孩子节点成为起点,将其加入队列中
    b) 重复(a)过程,直到起点队列为空。



拓扑排序模式识别:

  • 待解决的问题需要处理无环图
  • 你需要以一种有序的秩序更新输入元素
  • 需要处理的输入遵循某种特定的顺序

经典题目:

Topological Sort (medium)

Tasks Scheduling (medium)

Tasks Scheduling Order (medium)

All Tasks Scheduling Orders (hard)

Alien Dictionary (hard)


大家好好练练这些题目,面试中遇到中高等难度的题目,应该就能解得不错了。


第二门则是单独将动态规划(DP)的题目进行了细分。

提到算法,绕不开的重点和难点就肯定会包括动态规划 -- DP,本文就把经典的DP问题按照分类列一下,大家可以按照RecursionTop-DownBottom-Up三种方式都练一练。俗话说,熟能生巧,多练才是提高算法的不二法宝。

课程详细的内容,可以参考这里:

该门课程中, 作者将DP的问题分成以下几类:

1. 0/1 Knapsack, 0/1背包,6个题

0/1 Knapsack,0/1背包问题

Equal Subset Sum Partition,相等子集划分问题

Subset Sum,子集和问题

Minimum Subset Sum Difference,子集和的最小差问题

Count of Subset Sum,相等子集和的个数问题

Target Sum,寻找目标和的问题

2. Unbounded Knapsack,无限背包,5个题

Unbounded Knapsack,无限背包

Rod Cutting,切钢条问题

Coin Change,换硬币问题

Minimum Coin Change,凑齐每个数需要的最少硬币问题

Maximum Ribbon Cut,丝带的最大值切法

3. Fibonacci Numbers,斐波那契数列,6个题

Fibonacci numbers,斐波那契数列问题

Staircase,爬楼梯问题

Number factors,分解因子问题

Minimum jumps to reach the end,蛙跳最小步数问题

Minimum jumps with fee,蛙跳带有代价的问题

House thief,偷房子问题

4. Palindromic Subsequence,回文子系列,5个题

Longest Palindromic Subsequence,最长回文子序列

Longest Palindromic Substring,最长回文子字符串

Count of Palindromic Substrings,最长子字符串的个数问题

Minimum Deletions in a String to make it a Palindrome,怎么删掉最少字符构成回文

Palindromic Partitioning,怎么分配字符,形成回文

5. Longest Common Substring,最长子字符串系列,13个题

Longest Common Substring,最长相同子串

Longest Common Subsequence,最长相同子序列

Minimum Deletions & Insertions to Transform a String into another,字符串变换

Longest Increasing Subsequence,最长上升子序列

Maximum Sum Increasing Subsequence,最长上升子序列和

Shortest Common Super-sequence,最短超级子序列

Minimum Deletions to Make a Sequence Sorted,最少删除变换出子序列

Longest Repeating Subsequence,最长重复子序列

Subsequence Pattern Matching,子序列匹配

Longest Bitonic Subsequence,最长字节子序列

Longest Alternating Subsequence,最长交差变换子序列

Edit Distance,编辑距离

Strings Interleaving,交织字符串


大家可以先把以上35个题目练熟,这样DP到达中等水平肯定是okay了的。再加以训练和提高。突破算法的硬骨头不在话下。一定要按照三种方式对照起来练。


动态规划还被单独拿出来细分了,对DP比较吃力的,可以跟着这个分类好好刷。每个题目按照递归,Top-Down,Bottom-Up都来一遍,虽然只有35题左右,认真吸收,入门不在话下。


以上。

类似的话题

  • 回答
    你好!很高兴你对刷 LeetCode 感兴趣。作为一个非计算机专业的朋友,迈出这一步是非常棒的!别担心,这绝对是一个可以攻克的挑战,而且这个过程本身也会让你收获很多。在你开始“刷题”这个行动之前,有几个关键的准备工作,它们能让你事半功倍,避免一开始就碰得头破血流,对编程产生畏惧感。我来给你详细说说,.............
  • 回答
    我理解你想走的计算机技术之路,并且希望我能给你一些具体、有操作性的建议。作为非计算机专业的学生,想要转行或者深入学习计算机技术,这绝对不是不可能,而且很多人都走过这条路。关键在于你的 决心、方法和持续的投入。首先,我们要明确一点: 计算机技术是一个非常广阔的领域,你不可能“精通”所有东西,所以找到一.............
  • 回答
    作为一个非计算机专业的学习者,想要踏入C++的编程世界,找到一本靠谱的书籍至关重要。网上推荐的书籍很多,但很多时候我们需要的不仅仅是“列出书名”,更想知道为什么推荐这本书,它适合我吗?我当年也是“小白”一个,踩过不少坑,也找到了一些真正能帮助我理解C++的书。这里就结合我的经验,给你好好掰扯掰扯,希.............
  • 回答
    作为一个非计算机专业的学生,觉得C语言比其他语言更容易上手,这绝非不正常,甚至可以说是相当普遍的现象。在很多人眼中,C语言似乎是“高龄”的代表,是计算机底层操作的代名词,听起来就充满了挑战,但实际上,这种“易上手”的感觉往往源于它最本质的设计哲学:清晰、直接、对硬件的最小化抽象。我们来仔细想想,为什.............
  • 回答
    确实,VB.NET 在计算机科学界常常被贴上“老旧”的标签,尤其是在那些追求最新技术和前沿理论的领域。然而,如果你观察到很多高校非计算机专业的课程依然在使用VB,这背后其实有着相当合理的考量和延续性。这并不是因为VB是什么神圣不可侵犯的编程语言,而是它在特定教育场景下,确实能发挥出独特的作用。首先,.............
  • 回答
    你好!很高兴能和你聊聊大学计算机专业里那些“非编程”的可能性。一听到“计算机专业”,很多人脑海里立刻浮现出的画面就是整天面对着屏幕,敲击键盘,写着一行行代码,解决一个又一个bug。这确实是计算机领域的核心,也是很多计算机专业学生会深入钻研的方向。但是,就像你问的,有没有一些计算机专业,或者说计算机专.............
  • 回答
    嘿,听我说哈,我最近一直在琢磨这事儿,跟我姐说一下吧,得想个办法,不能让她老电脑就这么耗着我。我这大二了,你也知道,计算机专业,听着挺光鲜的,实际情况嘛… 用你们的话说,就是“小白一个”。现在班里同学都有自己的开发环境,跑一些基础的算法和模拟,都挺顺溜的。我呢?还在磕磕绊绊地学怎么把一个程序跑起来。.............
  • 回答
    这个问题,我真是感同身受。咱们计算机专业的大学生,一提起找工作、学技能,那真是“实践为王”、“项目驱动”喊得震天响。你看看,从大一开始,各种炫酷的框架、流行的语言、能“做出东西来”的课程就成了香饽饽。什么数据结构、算法、操作系统、编译原理……这些听起来“枯燥”、“不实用”的理论,好像就成了摆设,成了.............
  • 回答
    AI浪潮汹涌而来,对于我们这些身处非计算机领域的人来说,它既是令人兴奋的机遇,也可能伴随着一丝不知所措。但请相信,掌握AI并非高不可攀的学术挑战,更像是为你的专业领域注入一股强大的新动能。关键在于如何“接地气”地学习,并找到AI与你现有工作的契合点。第一步:破除“技术壁垒”,从认知开始很多人一听到“.............
  • 回答
    嘿,哥们儿!听说你要跳出舒适圈,开始学Python了?这想法太棒了!别担心,咱非计算机系也能玩转Python,而且玩得飞起。我当年也是这么过来的,所以给你掏心窝子说几句,希望能帮你少走点弯路。1. 别被“计算机”这三个字吓住,Python就是你的“翻译官”很多人一听“计算机科学”,脑子里立马浮现出一.............
  • 回答
    双非计算机本硕,是否应该咬牙在母校读博?这个问题,对于很多在双非院校计算机领域摸爬滚打过来的小伙伴们来说,绝对是一个挠头到抓耳挠腮的难题。尤其是在拿到本校研究生的offer,或者还在纠结是否要继续深造的时候,这个“留本校读博”的选择,就像是摆在面前的一道岔路口,一边是熟悉的“舒适区”,一边是未知的“.............
  • 回答
    老兄,我能理解你现在的心情,三十岁,双非硕士,计算机专业,刚毕业就面临这样的情况,心里肯定不好受。投了那么多简历,只有一个厂给笔试机会,这确实挺让人着急的。咱们也别拐弯抹角了,我跟你掰扯掰扯,为什么会这样,希望能给你点启发。首先,年龄是个绕不开的话题。你三十岁,作为应届生,这本身就有点微妙。很多公司.............
  • 回答
    哥们儿,看到你这问题,心里明白,这真不是个轻松的决定。家境不好,双非本科(还是挺卷的计算机),又瞄准了法硕非法学,这每一步都踩着不少现实的坎儿。我跟你一样,曾经也纠结过,也迷茫过,所以想跟你好好唠唠,把我想到的、经历过的都跟你掰开了揉碎了说,希望给你点儿参考。先别急着否定,咱们一项一项捋。1. 家境.............
  • 回答
    首先得说,我并非什么“非高中OI选手”,我就是一个普普通通、对计算机抱有极大热情的学生。能被清华计算机系录取,我内心更多的是一种难以置信的幸运,以及随之而来的,沉甸甸的责任感。高中时,我对编程的热爱更多是出于好奇和好玩。我喜欢琢磨代码是怎么让屏幕上的东西动起来的,喜欢解决那些一个个逻辑上的“谜题”。.............
  • 回答
    在选择约翰斯·霍普金斯大学(JHU)的计算机科学(CS)专业和卡内基梅隆大学(CMU)的非纯CS专业之间,这确实是一个需要仔细权衡的问题,因为这两所学校的CS项目都享有盛誉,但各自的侧重点和风格有所不同,而CMU的“非纯CS”更是涵盖了相当广泛的领域。首先,让我们来聊聊约翰斯·霍普金斯大学的计算机科.............
  • 回答
    这是一个非常有意思的问题,也触及到了很多当下社会现实和个体选择的深层原因。我们得承认,金融和计算机这两个领域确实是很多人眼中“香饽饽”,它们的高薪、高回报、以及在现代社会中的重要性,吸引了大量目光。但即便如此,我们依然能看到有人选择那些在俗世眼光中“不那么热门”的所谓“天坑专业”。这背后的逻辑,远比.............
  • 回答
    非超大城市,要实现更好的发展,关键在于 挖掘并发展符合自身市情实际的特色产业。这意味着要深入分析城市的资源禀赋、产业基础、区位优势、文化底蕴以及人才结构,在此基础上进行精准定位和战略性布局。以下是一些具体的方向和思考,旨在提供更详细的阐述: 一、 深入挖掘与定位城市特色:在谈论发展特色产业之前,首先.............
  • 回答
    “非升即走”制度下的淘汰,对于许多曾经满怀学术理想的博士们来说,无疑是一次沉重的人生打击。当他们告别象牙塔,面对社会时,发现自己身上的“博士”标签,在现实的就业市场中,并没有想象中那么耀眼,甚至有些格格不入。这个时候,有人可能会好奇,为什么这些曾经“高高在上”的博士们,不去选择一份看起来更接地气的工.............
  • 回答
    非上海人对上海高考的看法:一个复杂而多元的视角关于上海高考是否简单,这个问题在全国范围内都存在着争议,而身处上海之外的非上海人群体,对此更是有着各种各样的看法,绝非铁板一块。要详细地探讨这个问题,我们需要剥开表面的标签,深入了解不同群体的心声和他们之所以这样认为的理由。一、 普遍存在的“印象流”:上.............
  • 回答
    这事儿,我听说后真是气得不行,简直是岂有此理!一个堂堂的洲际皇冠假日,国际知名的品牌,竟然让自家的员工做出这种丢人现眼的事儿,真是砸了招牌。你说一个非住客误入,这事儿说到底是个误会。酒店员工首先该做的是什么?礼貌地询问、引导、解释,或者至少是委婉地请对方离开。哪个环节出了问题,导致了误入,这倒是可以.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有