Algorithm
文章平均质量分 65
刷刷刷刷刷算法啊啊啊啊!
Zheyuan Zou
中国科学技术大学2021级计算机系统结构硕士研究生,E-mail:[email protected]
展开
-
LeetCode刷题笔记和周赛题解总目录
LeetCode刷题笔记与周赛题解总目录原创 2023-02-16 16:13:10 · 299 阅读 · 0 评论 -
LeetCode——Weekly Contest 321
这段时间经历了组会、开题、回家等等,这才发现周赛已经打到325场了,而我还没有写完321场的题解记录,真是汗颜啊。原创 2022-12-20 11:23:09 · 391 阅读 · 0 评论 -
LeetCode——Weekly Contest 320(附动态规划解题思路)
LeetCode周赛第320场记录。原创 2022-11-29 16:23:24 · 667 阅读 · 0 评论 -
LeetCode——Weekly Contest 319
LeetCode周赛第319场记录原创 2022-11-18 12:48:24 · 708 阅读 · 0 评论 -
LeetCode——Weekly Contest 318
LeetCode周赛第318场记录原创 2022-11-11 11:03:22 · 371 阅读 · 0 评论 -
LeetCode——Weekly Contest 315&317
LeetCode周赛第315&317场记录原创 2022-10-30 20:32:30 · 528 阅读 · 0 评论 -
LeetCode——Weekly Contest 313
LeetCode周赛第313场记录。原创 2022-10-08 20:56:52 · 277 阅读 · 0 评论 -
LeetCode——Weekly Contest 312
LeetCode周赛第312场记录。原创 2022-09-28 23:53:55 · 342 阅读 · 0 评论 -
LeetCode题解内容迁移
LeetCode题解不再发布在CSDN,未来会就近记录在codetop.cc的个人题解,这样更加方便我快速复习。原创 2022-09-02 10:18:53 · 102 阅读 · 0 评论 -
LeetCode41——First Missing Positive——hashing in place & swap
这道题让我们找出一个数组中的缺失的第一个元素,也就是最小的一个正数,题面如下:其实如果只实现这个功能的话并不难,难点在于题目中对算法的时间和空间复杂度同时做出了约束,即时间复杂度是O(n)O(n)O(n),与此同时空间复杂度是O(1)O(1)O(1)。在完成这道题之前,有一个点非常重要的观察就是:对于长度为N的数组nums,其最小缺失的正数只会位于区间[1,N+1][1, N + 1][1,N+1]内,也就是说,长度为N的数组最多只会占用[1,N][1,N][1,N]这N个正整数,从而使缺失的第一个正原创 2022-06-28 21:18:04 · 189 阅读 · 0 评论 -
LeetCode144——Binary Tree Preorder Traversal——Iteration & Morris Traversal
一道很简单的题,二叉树的前序遍历,这道题一般三种解法:1.递归2.迭代3.Morris迭代算法这篇文章主要对后两者进行记录。一、递归法递归法基本上是所有人的首选,代码实现也比较简单,在这里从略,直接给出代码:class Solution { void preorder(TreeNode* root, vector<int>& Result) { if(!root) return; Result.pus.原创 2022-05-22 17:41:13 · 228 阅读 · 0 评论 -
LeetCode148——Sort List——merge sort
这道题的题面非常简单,就是简单的对一个乱序的链表进行排序。以往做的排序问题很多,但是大多数都是在数组中进行排序的。关于链表的排序做的比较少,这里专门开一贴来记录链表中的排序算法。注意这里所说的面向链表的排序算法特指game of pointers,也就是说这里不考虑有些人把数字取到vector里再sort一下放回链表的讨巧做法。一、插入排序这是我首先想到的算法,而且它确实非常适合链表这种数据结构。插入排序需要保留一个有序区,所以这里我用了[Head, Tail]这个区间来指出有序区域的范围,那么我原创 2022-05-15 17:17:48 · 215 阅读 · 0 评论 -
LeetCode69——Sqrt——Newton Method for gradient descent
这是一道很简单的题目,就是求某个整型数字的平方根,题面如下:这道题不难,首先最基本的可以使用迭代法来一个一个地尝试,但是这样的复杂度显然是O(n),属于所有算法中较差的一种。进阶一些的做法就是二分法来求解平方根,这样可以将算法的复杂度减小到O(logn\log{n}logn),但是要注意数据类型的位长,代码如下:// search x's sqrt in inteval [Low, High) long searchSqrt(int x, int Low, int High) {原创 2022-01-28 11:47:05 · 821 阅读 · 0 评论 -
LeetCode70——Climbing Stairs——DP & QuickPower Algorithm
这是一道简单题,题目要求如下:其实这道题很简单,我第一次做的时候使用的方法就是动态规划,但是因为没有使用滚动数组,所以在空间复杂度上差了一些。所以写这篇博客来记录一下从这道题中汲取的精华,一是滚动数组,二是矩阵的快速幂算法,后者是从官方题解中学到的。1.DP首先记录动态规划+滚动数组的方法:int climbStairs(int n) { /* allocate a DP array, DP[i] means the number原创 2021-11-28 23:09:04 · 132 阅读 · 0 评论 -
LeetCode143——ReorderList——3 alorithms combination
这道题要求将给定的一个单链表重排,具体要求如下所示:也就是说要求将原先的第一个结点后面接最后一个结点,然后接第二个结点,第二个结点后面接倒数第二个结点,以此类推。这道题我一开始用暴力法解的,就是直接按照题目要求重排链表,可以做但是代码效率会比较低。官方题解中提到的一种方法是三种对链表的常见操作组合起来完成本题的功能,也就是查询链表中点、反转链表、合并链表这三个动作。这一个题考查了三个小问题,因此知识点非常浓缩,下面是实现代码:首先实现查询链表中点的操作,这里使用了快慢指针算法。...原创 2021-11-26 21:00:18 · 247 阅读 · 0 评论 -
LeetCode42——接雨水——DP or Two Pointers
这是一道面试常考题,题面如下:意思就是在给出了数组之中,数组中的每一个元素都是代表了一个模板的长度,求这些木板围起来的空间所能容纳的水的体积。这道题官方题解给了三种方法:动态规划、单调栈和双指针。这里只把动态规划和双指针的解法记录下来。1.动态规划首先要发现一个规律,这个规律至关重要:一块木板上所能积蓄的水量 = min(这个木板以左的最高木板(含自身),这个木板以右的最高木板(含自身)) - 木板本身的高度,注意所谓以左以右的高度要包含自身,如果不包含会算出错误结果。如果不包含,那么假设有一序列为原创 2021-10-11 10:50:13 · 154 阅读 · 0 评论 -
LeetCode23——Merge K Sorted Lists——Priority Queue
这道题要求合并K个有序链表,题面如下。合并两个已排序链表是这类问题的一个基本问题,但是当链表数目从2变成K时,如何寻找下一个要插入的结点就变成了一个最重要的问题。可以通过每次遍历每个链表开头的结点来得到(复杂度O(k))当前应该插入的最小值的结点,但是这样的复杂性太高。所以这道题必须引入一个数据结构来帮助我们快速筛选出要插入的下一个结点,我选择的是优先级队列(priority_queue)。当然,因为实现优先级队列的STL底层数据结构是堆,所以手写一个堆来做效果是一致的。...原创 2021-10-09 20:08:51 · 109 阅读 · 0 评论 -
LeetCode92——Reverse Linked List II——头插法
这道题要求将一个链表中的指定部分反转,而保持其他成分不变,题面要求如下:记录这道题的目的在于提醒自己头结点(DummyNode)在链表问题中的重要性。头结点的存在使得首结点成为一个普通的结点,这样为统一操作和简化代码提供了大量的方便。如果不使用头结点,在一些问题中就必须要为第一个结点设置大量的条件检查和情况讨论,比如此题。我的思路非常简单,就是将要翻转的链表段摘出来,按照一般的链表反转将其反转再接回去。所以可见我们需要下面四个关键位置(红色结点是需要翻转的链表):predecessor和succes原创 2021-09-25 16:26:57 · 164 阅读 · 0 评论 -
LeetCode208——Implementation Of Trie
前缀树,或者叫字典树,是一种典型的空间换时间的字符串搜索策略。它通过将字符串逐字符的存放进一棵树的结构中,从而将一个字符串的搜索时间降至线性。LeetCode208就是关于字典树的实现,题面如下:一个简单的键树示意图如下。红色字母表示单词的结尾,那么这棵树中存储的单词有:ab,abc,ade对于某一个结点,不仅要存储它是否是某一个单词的结尾,还要存储指向其下一个字符的指针。类Trie包含的私有数据如下: /*using dynamic memory allocation*/ bool En原创 2021-09-18 17:53:29 · 306 阅读 · 0 评论 -
LeetCode406——Permutation——dfs+backtrack
这道题是求一个指定序列的全排列,使用的算法思想是非常基本的深度优先搜索(dfs)+回溯(backtrack)。因为解法非常典型并且具有代表性,所以在此加以总结。深度优先搜索意味着一次搜索将会进行到搜索空间的最深处才停止,而回溯则意味着解状态的回退,也就是上一步深度搜索动作的对应解除。在解决问题的代码中,Current表示当前已经生成的排列,Used数组是标明某个数字是否已经使用的标志数组。核心函数dfs的代码如下:void dfs( vector<vector<int>>&am原创 2021-08-16 20:45:23 · 78 阅读 · 0 评论 -
LeetCode142——Linked List Cycle II
带环链表问题的进阶版,不仅要判断是否存在环,还要找出环回的位置。题面如下:这道题在原本快慢指针的基础上加入了更多的操作细节,简而言之,快慢指针的相遇与否可以说明链表中是否存在环路。但是这并不能直接反应出相交的位置,这里面涉及到一个简单的数学推导:官方题解中给出了完整的推导总而言之,这个推出的结论就是本题的解题关键,也是难点:当Slow和Fast指针相遇时,我们再使用一个指针从链表头部与Slow指针一齐向后运动,最终两者一定会交汇在链表的环回处。这个结论在理解原理的基础上可以记下,下面准备给出源代码原创 2021-08-04 10:55:07 · 93 阅读 · 0 评论 -
LeetCode103——zigzagLevelOrder of binary tree
这道题做的是二叉树的之字形遍历,之字形遍历本质就是层序遍历的变式问题,题面如下:这道题和LeetCode102题同宗同源,不过难度更大一些,就以这道题为例将问题做一个总结。首先补充一点,查看示例代码可以发现期望返回的结果类型是vector嵌套另一个vector,也就是说答案希望将一个层次中的结点全部放在一个内层vector里,再保存到一个更大的外层vector中表示全部遍历的结果。这需要我们做一些处理,也就是我们得知道各个层次之间结点的界限,不能出现将一层的结点放到上一层或下一层的情况,否则内层的vec原创 2021-07-20 16:24:24 · 128 阅读 · 0 评论 -
LeetCode160 & LeetCode141——double pointers to solve the linked list
一次总结两道题,原创 2021-06-27 16:53:56 · 81 阅读 · 0 评论 -
LeetCode21——Merge two sorted lists——Iteration or recursion
一道常规的题目,即合并两个有序的链表,题面如下:合并(Merge)这一步往往是归并排序(MergeSort)的一个子步骤,一个需要注意的点是。由于我们合并的是链表,所以不需要额外申请存储空间,完全可以通过改变指针的方式来实现两个链表的有序合并,所以在合并过程中有new开辟新的节点的操作一定不是最优的。反过来说,如果是向量这种连续的存储空间实现归并,那么是需要额外空间来支持的。比较易于掌握的代码写法当然是迭代式合并,为了方便处理先申请一个头节点Result来简化操作,也是为了记录下最终合成链表的开始位置原创 2021-05-12 16:55:45 · 110 阅读 · 0 评论 -
LeetCode53——Maximum Subarray——3 different methods
这道题目让我们求出一个线性数组中最大的连续子数组的和,题目要求如下:这道题的题目很简单,解法也有多种,在这里总结3种解法去解决这个问题,在比较中加深对不同思路算法的理解,这三种算法是动态规划、模拟法、滑动窗口。首先是动态规划法,正如我们之前提过的,递推形式的动态规划基本上就是三部曲:1.确定DP数组的含义2.递推奠基3.基于递推方程来进行反复递推,直到最终答案就这道题而言,DP[i]的含义是以nums[i]为结尾的最大的连续子数组的和,注意一定要以nums[i]为子数组的最后一个元素。在此基础原创 2021-04-26 22:19:44 · 98 阅读 · 0 评论 -
LeetCode912——sort an array—— quick sort algorithm
这就是一道简单的数组排序问题,借这道题回顾和复习一下快速排序算法的实现。快速排序被普遍认为是当下速度最快的排序算法之一,在处理大规模数据时其性能表现一般很好。然而,快速排序算法是输入敏感的(Input-Sensitive)算法,也就是其实际执行的耗时和输入序列的情况密切相关,也和我们找到的划分点Pivot在序列中排序之后的实际位置有关。快速排序算法的思想很简单,也就是在待排序序列中按一定策略找出一个划分点元素Pivot,将比Pivot小的元素排列在Pivot左边,比Pivot大的元素排在Pivot右边。原创 2021-04-25 17:32:40 · 87 阅读 · 0 评论 -
LeetCode146——LRU Cache——DS Design
这是一道别具一格的题目,不同于一般的考察算法的问题,这道题是一道综合性颇强的设计类问题。题目给定要实现的功能简介,并对期望的算法时间复杂度做出了要求,下面是这道题目的具体要求:LRU(Least Recently Used,最近最少使用)对于对计算机稍有了解的人来说都不陌生,在cache和页表等等很多系统机制的替换策略中均有它的身影。这道题让我们实现一个模拟的LRU机制,并实现其中的get(获取数据),put(放置数据)两种操作,并且希望我们在O(1)的时间复杂度中完成,是一道综合考察数据结构和设计能力原创 2021-04-21 17:27:16 · 124 阅读 · 0 评论 -
LeetCode215——the kth largest element——heap sort
这道题是寻找一串数组中第k个最大的元素,题目要求如下:特别强调,不需要寻找不同的元素。这道题可以使用排序算法直接来解决,手写快排之后返回nums[k - 1]即可。当然这道题还可以选择使用STL库直接解决,就像这样:// using generic algorithm and lambda expression to solve the problemsort(nums.begin(), nums.end(), [](const int& a, const int& b) ->原创 2021-04-18 16:42:00 · 129 阅读 · 0 评论 -
LeetCode206——反转链表
一道经典的数据结构初学者问题,主要考察指针的修改和用法:就像题目中进阶要求所说的那样,这道题有两种解法:迭代和递归。但其实它们的核心操作都是一样的,就是代码中修改指针的部分,当然这题需要一前一后两个指针跟随着一步步将链表逆置。下面贴出我的代码,首先是递归写法:// recursive methodvoid recursive(ListNode*& Ahead, ListNode*& Follow){ if(Ahead == nullptr) return;原创 2021-04-15 16:23:01 · 86 阅读 · 0 评论 -
LeetCode32——next permutation
这是一道关于数组排列的题目,题面如下:事实上,熟悉C++ STL的朋友一看到这道题,应该就联想到这是STL中已经提供的的一个泛型算法。在STL中的算法功能和此题描述的完全一致,只不过在STL中返回值是bool类型,如果存在下一个更大的排列,那么就返回true,并将容器修改为下一个更大的排列。C++ Primer 5th edition中附录解释如下:所以其实这道题的AC代码就是…// using STL generic algorithm directly, hahaha... next_per原创 2021-04-09 23:29:56 · 166 阅读 · 0 评论 -
LeetCode0022——括号生成——DFS
这道题是一道基于深度优先搜索的字符串类问题,题目描述如下:这道题也就是要挨个找出所有有效的的成对的括号,有效的可以总结如下:1)开头的第一个元素必是左括号2)只有前面还有未配对的左括号,才可以有右括号出现3)使用的括号对数恰好为n所以这题的深度优先搜索是有条件约束的,给出我写的代码: /* Result is the vector storing the result string LeftCounter is the number of Left bracket can be原创 2021-04-07 19:04:42 · 127 阅读 · 0 评论 -
Leetcode0002——Add Two Numbers——Linked List
这是一道关于单向链表的题目,考察的也就是单向链表的构建和遍历。题目如下:单链表的遍历以普通的加法为载体呈现,题意很好理解。我写了两个版本的代码,一个是开启了一个新的链表来存储结果,一个是就地加到较长的链表上去。从思路上不难看出,前者更省时间(因为不需要额外判断链表长短,直接随加随开新的节点),后者更省空间。这里给出第二种解法的代码:1.首先我们需要写一个函数来得到链表L1和L2的长度,代码如下:// get the length of linked listint getListLength(原创 2021-03-29 20:52:59 · 63 阅读 · 0 评论 -
LeetCode0015——3 Sum——Two Pointers
这道题是双指针问题的一个变式问题,但是一开始处理起来会显得比较棘手。因为它同时涉及到了三个指针,三个指针的搜索范围有重叠,但是在最终输出结果里要求不能有重复的三元组。题目详情如下:解决这个问题的时候可以使用转化的思想,将三个指针中的一个暂时固定(fixed),剩下两个指针像传统的双指针那样工作。双指针分为对撞指针和快慢指针。这样的题目显然是在寻找正负数相抵消的情况,是对撞指针擅长处理的问题。対撞指针还需要遍历的序列有序,所以可以想见需要事先对输入数组进行排序。为了不让结果含有重复的三元组,我们需要在原创 2021-03-26 19:30:36 · 112 阅读 · 0 评论 -
LeetCode98——Is It A Binary Seach Tree?
一道很经典的算法题,也应该是所有计算机专业学生在初学数据结构时做过的问题,尽管如此,我还是想把它写下来,这道问题就是判断一棵二叉树是否为二叉搜索树(BST)?在LeetCode上我写了两种解法,一种就是按照定义递归的把条件写出来再判断(直接法),另一种就是利用BST的性质:中序遍历结果为升序(性质法),注意空树是符合BST定义的。首先是直接法,其实就是定义的代码翻译:(1)节点的左子树只包含小于当前节点的数。(2)节点的右子树只包含大于当前节点的数。(3)所有左子树和右子树自身必须也是二叉搜索树。原创 2021-03-23 11:38:16 · 65 阅读 · 0 评论 -
11.Containers with most water——Two Pointers
双指针法是一种求解思想,它不具体指某一种算法。双指针法在求解数组、链表相关的问题时使用的很多,在数组有序时尤甚。常用的双指针法类型有対撞指针和快慢指针,前者让两个指针分别指向线性空间的头和尾,按照一定的条件向中间慢慢靠近直至两者相遇,算法结束;后者则是让两个指针从同一侧出发,按照不同的步长向前迈进。快慢指针的算法题我做过一道关于求解链表中是否存在环路的问题,那道题使用了快慢指针,今天这道题则是対撞指针。题目如下:求解思路如下:/* 下面这个代码效率不是最高的,应该还有其他大神有更好的方法。 其原创 2021-03-09 11:32:38 · 78 阅读 · 0 评论 -
Leetcode0062 Unique Path——Dynamic Programming
一道经典的动态规划题,题面如下:机器人要从左上角走到MxN的网格的右下角,每次只能向左和向右走,m n均小于100,问路径总数。解法如下:/*递推法解动态规划一般分为以下几步,个人经验*//*1.明确DP数组的含义:DP[m][n]表示从原点(0, 0)出发,到(m,n)的路径总数*//*2.递推奠基:明确那些已经明确答案的数组元素,将它们在递推前初始化*//*3.递推:找到递推规律,迭代求解非奠基部分的答案*//*下面的代码就是按照这个顺序来写的*/int uniquePaths(int原创 2021-03-07 10:12:07 · 92 阅读 · 0 评论 -
面试题17.10.——主要元素——Boyer-Moore Majority Vote Algorithm
又是感冒的一天,完全看不下去任何东西,就来刷算法题了…首先来看看题目:数组中占比超过一半的元素称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回-1。示例 1:输入:[1,2,5,9,5,9,5,5,5] 输出:5示例 2:输入:[3,2] 输出:-1示例 3:输入:[2,2,1,1,1,2,2] 输出:2看到这道题我的第一想法还是做Hash计数,但是数组最大元素不确定,这时候很难开辟一个合适大小的数组。写这篇文章还是为了记录一种之前没学过的算法(菜哭了orz):Boy原创 2020-12-15 16:25:51 · 132 阅读 · 0 评论 -
LeetCode 08.11硬币:Dynamic Programming(1)
LeetCode 08.11硬币最近在集中做LeetCode上的动态规划类的问题。在做题(看题解)过程中,发现了很多有意思的思路和方法。在这里做个简单的总结和梳理:硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)示例1:输入: n = 5输出:2解释: 有两种方式可以凑成总金额:5=55=1+1+1+1+1示例2:输入: n = 10 输出:4 解释: 有四种方式可以凑成总金原创 2020-12-14 21:59:37 · 93 阅读 · 0 评论