
算法/数据结构
刷题记录
源大郎
这个作者很懒,什么都没留下…
展开
-
Leetcode中级算法排序与搜索(3-8)动态规划(1-2)
写个最小堆呗,构建堆时用上浮算法(就是添加于末尾,若小于父节点,交换,直到到根节点为止),堆构建完成后,使用下沉算法,若大于根节点,与它交换,然后判断是否大于下面的值,直到最后一层。父节点 = 子结点-1>>1 子结点 = (父节点<<1)+1 or 前一个节点+1.class Solution(object): class heap: __slots__ = ['k','h','size'] def __init__(self,k): .原创 2020-09-13 13:30:31 · 388 阅读 · 0 评论 -
每周LeetCode 中级算法 回溯算法1~5 和排序算法1~2
电话号码组合思路:遍历每层的输入,当层次“溢出”回溯class Solution(object): def letterCombinations(self, digits): """ :type digits: str :rtype: List[str] """ if len(digits)==0: return [] dic = {str(i+1):[chr(ord('a'原创 2020-09-06 00:22:09 · 264 阅读 · 0 评论 -
每周LeetCode 中级算法 链表(1~3) 以及 树和图(1~5)
1.链表思路: 每个节点对应相加再加上上一次进位的值。然后再保存这次进位,下次用,可以用另外个链表存,也可以存在其中一个链表上,不过第二个有一个问题,不晓得最后哪个链表长。同样...原创 2020-08-29 23:06:52 · 334 阅读 · 0 评论 -
本周算法题总结——中级算法专题(1~6 数组和字符串)
思路:三个数字和为0,必然除非仨0,要不然就是就肯定至少一个与其他符号相反,这样就需要统计正负数,那排个序呗,然后双指针扫,不过需要仨数,那就用一个数字当桩,然后另外俩在左右两边,小于0则左指针右移,大右左…...原创 2020-08-22 01:25:18 · 224 阅读 · 0 评论 -
《剑指Offer》第1,2章面试流程与基础知识
第一章项目介绍可按照STAR模型。S:背景T:自己完成的任务A:为了完成任务怎么做的(什么工具什么平台什么技术)R:成果,实现了怎样的效果,最好能够量化高质量的代码边界值的处理,特殊输入,负面输入,最好先写单元测试再写实现。遇到复杂问题有三个理解的思路:1.画图 2.举例 3.分解而且还需要关注时间复杂度,空间复杂度等。提问环节问相应的人,相应的问题。基础知识第一章可能是基础知识吧,都比较简单,书中给出的一些解决思路还是有点妙妙。突然觉得这书用于入门也挺好的实现Singleto原创 2020-06-29 02:09:24 · 264 阅读 · 0 评论 -
LeetCode探索下的字节跳动面试专题全记录
前几天做完了这个专题,还是整理一下吧,虽然说着是字节专题,不过感觉题目都不算难,不过有一定的启发性,题目比较连惯,像数据结构那一节就是循序渐进的。字符串1.无重复字符的最长子串比较简单粗暴的想法就是没尝试添加一个字符,则回溯与前面比较,如果出现重复的,则将开始点设为重复字符位置+1,这样的时间复杂度为O(n2).当然还有巧妙的方法,滑动窗口,时间复杂度O(n)借助HashMap完成,map的key为字符,value为上一次出现的索引。如果遇到存在了,则更新start为重复元素的索引+1 和 .原创 2020-06-24 23:22:54 · 621 阅读 · 0 评论 -
LRU使用LinkedHashMap实现(主要分析LinkedHashMap的原理)
LC上有这么一道题让实现一个LRU,LRU如上描述就是一个有容量限制当容量满时会自动移除最后一次时间时间最晚的缓存结构。想到Redis中的ZSET结构(主要是想到了昨天学的漏斗限流…),不过只能存储key不能存储value…在Java中也有排序表的结构,可以使用一个TreeMap,key为一个HashMap,HashMap存储题目中的key和value,TreeMap的value为操作时间戳,每访问一次或者修改一次就更新。如果超出容量设定了就移除时间戳最靠前的那一个。不过Java中有种更合适于干这事.原创 2020-06-17 02:51:42 · 537 阅读 · 0 评论 -
LeetCode刷题记录,复原IP地址(深搜+回溯)
由于IP必须有4段,且大小范围为0~255之间,所以s的长度必须在 4 ~12之间。那么我们可以每一段可以尝试截取1 ~3位,至少需要保证当前剩余的数字不会超出剩余的段数的最大要求。而且截取的数字需要在大小范围内,如果这俩条件满足的话,就是一种正确的情况。class Solution { List<String> ans = new ArrayList<>(); public List<String> restoreIpAddresses(Strin.原创 2020-06-07 01:10:46 · 189 阅读 · 0 评论 -
CodeForces #647 Div.2 ABC
A题意描述问一个数能否通过有限次左移1,2,3位或者右移1,2,3位变成另一个数。思路只需要知道较小那个数通过左移(扩大为原来的2倍)操作能否变成较大那个数就行了,然后为了使得操作次数最少,所以能移动3次就不移动2次。import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in原创 2020-06-05 17:17:40 · 183 阅读 · 0 评论 -
LeetCode刷题记录,字符串相乘(模拟竖式计算),简化路径(栈)
这种用字符串模拟数字,无论加法乘法一般都是模拟人竖式计算的过程,比如加法可以拆解为每一位对应的加法,然后只保留余数,进位就放到下一位之后一起加。这里乘法也是一个道理,乘法根据分配律可以拆分为,比如123 x 456 = 123x(400+50 +6) ,只需要用被拆开的数字分别与123的每一位相乘即可,如果存在进位就加到下一位的结果上。当每个位数乘完再全部加起来就是答案了。class Solution { public String multiply(String num1, String n.原创 2020-06-05 16:53:12 · 198 阅读 · 0 评论 -
字符串的排列(双指针 滑动窗口)
用双指针来完成这题。既然顺序无关也就说使串中所有元素的和为零即可。可以使用一个长度为256的数组来装字符元素,可以使用HashMap来完成,首先清点一下s1,每个字符的数量。然后用右指针遍历s2串,left指针则指向right的前面,如果right所指的位置是目标元素,则就可以该处字符减小1,要不然map中该元素就为-1,则就说明当前字符不是在目标范围内的,左指针需要右移,并将它们还原为0。一直到left和right构成的滑动窗口的范围达到s1数组的长度时,这时就算找到了,如果遍历完s2串都没有找到.原创 2020-06-03 01:22:37 · 129 阅读 · 0 评论 -
CodeForces #646 Div.2 B
B题给定一个数列,该数列由0和1构成,如果其中含有010或者101的子序列,则是不好的序列, 需要用最少的操作将它变为好序列。思路,有三种格式的序列是好的,比如00000…0000,111…111 ,1…110…000,000…0111…1;那么其他的形式只要能转换为这四种之一即可。那么可以求1的前缀和,然后先判断转换为全0或者全1的情况,然后再尝试逐一转换为前部分全0后部分全1 或者 前部分全1后部分全0.来看这2n+2种情况谁最小。import java.util.Scanner;原创 2020-06-01 18:16:00 · 127 阅读 · 0 评论 -
每日算法——最小路径和,地下城游戏
要想知道到达(x,y)点的路径和就为(x,y)=选择(x-1,y)中(x,y-1)较小那个历史路径+当前值.这就找到套娃问题了。dp[i][j]定义:到达i,j位置时的路劲和转移方程: dp[i][j] = min(dp[i-1][j],dp[i][j-1])+nums[i][j]初始化: 由于第一行与第一列只有一种来路,所以需要将他们预先处理,有两种方式,1.扩张出去,再扩张出去的那一行/列置为最大值2.特殊处理,将第一行与第一列预先预处理了(一直加到最后即可)。空间压缩: 由于每个点的结果仅与.原创 2020-06-01 01:09:20 · 460 阅读 · 0 评论 -
CodeForeces Edu #88 Div.2 (A~C)
A题描述k个人选牌,牌共有n张,其中有m张鬼牌,如果某人手里的鬼牌比其他人多,那么多的数量就是赢的分数,如果有两个高分则算做0分。(淦,这题我理解成每个人手里的鬼牌都不能一样了,俺就说A题怎么这么麻烦…)输入:第一行t个测试样例(1≤t≤500) 测试样例格式 n m k (2≤n≤50, 0≤m≤n, 2≤k≤n)输出:最大得分。思路第一个人,肯定全抓鬼牌,如果被抓完了,那得分就是鬼牌数。如果没有抓完,就剩下的人均分,如果分不干净(有余数),再在基础上+1.然后再用第一个人手里的全鬼牌原创 2020-05-30 03:46:32 · 173 阅读 · 0 评论 -
每日算法——动规高频题【3】
1 <= target(目标位置) <= 10000啊那个R仅仅是转向还有刹车的意思,并不一样要后开一个位置,俺就是看着结果莫名其妙的。能够直接到达的位置是2n -1这种类型的位置,如果无法到达就有两种清空。1.开过了,得倒回来,这种情况比较简单,只需加上开到过了的那个位置的操作数(n)+开回来的次数(2n-1-x时的操作数)+掉头的操作。2.开到前一个正好(2n-1-1)时就麻烦了,2n-1 ~x的位置也是个套娃结构,这里停了一下,这时速度降为0了,然后开到下一个位置,可是有时候开一.原创 2020-05-29 03:47:28 · 108 阅读 · 0 评论 -
CodeForces#645 div.2(A~D)
A题:描述在一个公园修建最少的路灯,照亮整片公园,路灯的照亮范围是所在边界的附近两块。输入:第一行为本次测试用例数量(1<=t<=104),之后为公园的长宽(1<=n,m<=104)输出需要的路灯数思路就跟以前看过一个盖方块的思维题一样给一个棋盘(国际象棋那种),然后用一个1*2的方块来逐一覆盖棋盘,方块之间不能有重叠或者漏盖,请问能否覆盖完全。这个思维题很简单,如果这个面积可以被2整除,那必然可以完全覆盖,因为它的最小单位面积就是2。再回到这道题,我们想要最少的原创 2020-05-28 01:06:11 · 151 阅读 · 0 评论 -
每日算法——动态规划高频题【2】不同的二叉搜索树Ⅱ,编辑距离
这题肯定首先想到暴力回溯法啊。所有的点尝试完所有可能的情况。而且是二叉搜索树必然有左>根>右的规律。每次尝试某个点作为当前根节点时,它已左的到它的父节点已右的都是它的左子树,反之它已右的父节点已左的都是它的右子树。代码如下:class Solution { public List<TreeNode> generateTrees(int n) { if(n==0){ return new ArrayList(); .原创 2020-05-27 02:04:17 · 189 阅读 · 1 评论 -
每日算法——动态规划高频题【1】正则表达式
俺做过这题,这是一个线性dp题 ,线性dp就是子问题是单向的 (意会一下,区间dp是双向)这个问题就是求字符串能否可以正确匹配,如果一个串要与某段字符串匹配上,那么它肯定前面匹配上了,然后现在这个位置也匹配上了,由于有*的存在,所以涉及到状态回溯,* 可以匹配1个或者多个或者一个也不匹配。一个都不匹配又分为两种情况,一种是确实匹配不上,另一种就是可以不匹配.如果是因为匹配不上而不匹配,则当前的状态则于两个字符前一致。另一种可以匹配,三种情况有一种可以匹配上,那就算能匹配上。(动态规划的.原创 2020-05-26 03:06:12 · 136 阅读 · 0 评论 -
每日算法——动态规划高频题【0】最长回文子串,最大序列和,最大矩形
这题俺做过,区间dp,查找一个字符串是否为回文,首先它两边得是相同的,然后中间得是个回文串,这样套娃子问题就找到了,判断中间的是不是回文。dp[i][j]:i~j范围内是否为回文串。转移方程:dp[i][j] = s[i]==s[j]&&(i-j<3||dp[i-1][j+1]])class Solution { public String longestPalindrome(String s) { int len = s.length(); .原创 2020-05-25 02:22:53 · 121 阅读 · 0 评论 -
KMP算法实现
又是群里小伙伴在问,想到俺以前也只是看过相关文章,知道个大概,如果面试到,还真不一定能写出来。便想着试试。目前我看过两种思路:1.类动态规划的方式2.比较前缀和后缀无论是哪种思路,匹配原理都是一样的,不过求状态转移数组的方式不一样。第一种,类动态规划的思路这种思路就与昨天做的骑士拨号器算法题类似,不过“拨号”范围变为了256个ASCII码,而状态转移的规则由匹配串得来。比如匹配串为ababacba下表表示了如果主串字符为啥时,下一个字符应该用匹配串的哪一位去匹配。(0~n)尝试匹配原创 2020-05-24 20:49:13 · 149 阅读 · 0 评论 -
每日算法——数位DP
数位DP,一般给定一定数值范围内然后求满足某个条件的总数,就可以用此方法了。以这题来说,就是将数位拆分为各个位数存入一个数组。因为找存在重复数字的比较麻烦(2,3,4个重复数字啥啥的),就转换为找不重复的。在[0,N]之间,低于N最高位数的数字(最高位取0),所有数字范围是可以任选的。那么就可以按位用排列来做Anm而取到最高位就需要根据下一位来判断了,又可以分为两种情况,上面那种情况和现在这种情况,不过唯一不同的是,不允许使用重复的数字(因为前面数字已经固定了所以选择范围就不一样了)。而且需要注意.原创 2020-05-23 03:53:52 · 402 阅读 · 0 评论 -
每日算法——最长连续序列,合并链表,合并k个链表等
啊啊啊这道题我居然做过,我一点印象都没有了。先来看一下目标,找连续的序列,连续的意味着 最小值+长度-1 = 最大值,且中间值相差为1.这题有三种思路或者说两种。1.动态规划:像这种最长序列啊,子串啊,之类的第一反应就是动态规划啦比较常规,比起暴力多了一个判断,只有当它前一个值不存在时才重看(因为这是可能的最长开始),一直查找到它的最长的情况,然后换下一个数,这种算法表面上是O(n^2),其实是O(n),添加到set中,n次,然后之后只有可能只会在出现新的可能的开始点时,才会执行操作,对应的.原创 2020-05-22 01:13:27 · 188 阅读 · 0 评论 -
每日一题——跳台阶和变态跳台阶
这个就是斐波那契数列,因为可以选择的范围是1,2;所以想要直到跳上n级别,那就需要跳上F(n) = F(n-1)+F(n-2);不过初始条件变为,1阶台阶时有一种方案,2阶台阶时有两种方案public class Solution { public int JumpFloor(int target) { int pre_1=1,pre_2=1,curr=1; for(int i=2;i<target+1;i++){ curr = .原创 2020-05-21 17:30:13 · 175 阅读 · 0 评论 -
每天一道算法题——斐波那契数列
啊送分题(想起有次做某厂测试的笔试,大家都是这种题,而我是一个字符串重复匹配???)这题递归做很简单,几行代码完事。lambda的性能不如直接写,超时了。UnaryOperator<Integer> ff; public int Fibonacci(int n){ ff = i->i<=1?i:(ff.apply(i-1)+ff.apply(i-2)); return ff.apply(n); }但是它的效率并不高,可以画下.原创 2020-05-20 18:00:21 · 358 阅读 · 0 评论 -
每天一道算法题——两个栈实现队列
这题我在同花顺笔试里遇到过栈是LIFO形式的,后进先出,总是弹栈顶的。队列是FIFO形式的,先进先出,总是出队尾。有两个栈,就可以倒腾一遍嘛,两次后进先出(将原来的栈顶元素置于栈底了),不就模拟了先进先出。import java.util.Stack;import java.util.stream.IntStream;public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); .原创 2020-05-18 17:01:34 · 192 阅读 · 0 评论 -
一天一道算法题——重建二叉树
就是根据前序遍历和中序遍历确立二叉树呗。所谓前序就是中左右的顺序。中序就是左中右。所以前序的第一个节点肯定是根节点,而在中序里,那根节点以左的肯定是左子树,以右肯定是右子树,同理前序第二个节点如果是在中序以左的,肯定左子树的根节点…我们就找到规律啦。有点深度优先的思想。—以前序的某点作为父节点—划分以此节点的左右子树(用中序划分)—挑选下一个父节点,左子树是在前序数组,原父节点的索引+1,右子树是在原父节点的索引+左子树大小+1.import java.util.stream.IntStre.原创 2020-05-17 20:58:40 · 130 阅读 · 0 评论 -
一天一道算法题——从尾到头打印链表
这题如果做过反转链表的话,简直就是送分题。先用递归做嘛,利用递归天生的栈结构,搜到底层然后回溯时添加进list。import java.util.ArrayList;import java.util.List;public class Solution { public ArrayList<Integer> printListFromTailToHead(ListNode listNode) { ArrayList<Integer> list = n.原创 2020-05-16 16:39:04 · 114 阅读 · 0 评论 -
一天一道算法题——替换空格
本来疑惑为啥replace方法过不了,试了下replaceAll方法也过不了,俺就知道了,估计被屏蔽了吧?然后我又试了转换成char数组一个一个自己比对,然后还是数组越界?疑惑不解?然后我又换到讨论页面界面提交一毛一样的代码过了,这是出bug了?public class Solution { public static String replaceSpace(StringBuffer str) { StringBuilder sb = new StringBuilder(); .原创 2020-05-16 02:04:11 · 149 阅读 · 0 评论 -
一天一道算法题——二维数组查找(二分查找)
我的思路:看到有顺序的数组要就有用二分查找的觉悟而且还因为,上下行间同列也有大小对应关系所以可以直接判断最后个数是否小于目标值,若小于,那就不用比了换行。(有个挺意思的点在于,每轮判断末尾数是否小于目标数的操作的时间居然大于直接二分查找的时间(看来数据规模并不算大))public class Solution { public static boolean Find(int target, int [][] array) { for(int i=0;i<array.le.原创 2020-05-14 22:41:10 · 210 阅读 · 0 评论 -
记录一道面试算法题餐馆问题(贪心和动态规划)
太难受了,面试时看成桌子都是一样大的了。一拍脑袋就用动态规划做了…害估计凉了。我当时的思路是这样的(并不是此题正确思路,没兴趣可跳过):假如桌子的大小时一致的,我们可以转换为一个普通的01背包问题,客人就是选与不选的问题,不过需要将客人的人数除以桌子容量向上取整转换为需要桌子的张数。如果想要知道n批顾客,i张桌子最大收益为多少,那么只要知道i-1张再加上目前可供选择的没入座的客人批次即可。定义:dp[i][j] :第i批客人来时j个桌子最大收益为多少转移方程:x为此次客人需要的桌子数,rmb.原创 2020-05-13 00:00:22 · 1266 阅读 · 0 评论 -
LeetCode多线程题目——交替打印FooBar(用等待通知机制构造屏障)
想要交替输出,两边线程就需要通信,因为只有两个线程分别调用两个方法,所以仅需要使用一个布尔类型的量作为信号即可,用flag的两种状态来分别限制两者,如果为真,foo线程等待 ,bra执行,执行完毕唤醒foo如果为假,bar线程等待,foo执行,执行完毕唤醒bar以下分别ReentrantLock和synchronized代码块来实现。class FooBar { private int n; private ReentrantLock lock = new ReentrantLock.原创 2020-05-10 17:34:26 · 266 阅读 · 0 评论 -
动态规划总结——背包dp(基于LeetCode题目)
题目汇总这类问题阔以说是笔试最常出现的题目了(线性dp也挺常见,啥最长上升子序列啥啥的)。这类问题如果不是太难基本上阔以套模板的。抽象一下就是有一个收益尽可能大的目标,有一个其他消耗,在允许的消耗范围内使得收益最大。子问题也很好想,就是某个消耗限制下最大的收益。这类问题分为01背包,多重背包,完全背包。01背包就是同个有价值的消耗都只有一个。多重背包每个有价值的消耗有有限个(可以转换为01背包)。完全背包就是每个有价值的消耗有无穷个。这是一个01背包问题。那个数组里的就是消耗。价值:原创 2020-05-09 01:45:27 · 361 阅读 · 0 评论 -
动态规划总结——区间dp 最长回文子串
上次做过一个子序列,而这次题目是子串而且需要返回具体子串是哪个不过这次我们采用其他的思路。用类似线性dp的写法,不过我觉得本质仍然是区间dp。每次找到前面子串是否为回文串,再用一个值来记录最大值。一个字符串如果是回文串那么它肯定首尾相等且中间是回文串。这俩条件缺一不可。那个中间的字符串是否为回文串就是我们需要记到dp数组里的了。这样我们就可以用一个dp数组记录下前面串是否为回文,每次判...原创 2020-05-08 17:16:03 · 342 阅读 · 0 评论 -
二叉搜索树(实现增删查,前中后层次遍历、获取深度和结点数量)
俺一直觉得二叉树是一个天然适合用递归处理的结构,只能从顶开始,面前只有两条路,不断将问题细化直到最底,然后再倒回去选择另一种路。而二叉搜索树的结构就是在二叉树的基础上,多了一个规则,某结点的左子树的结点总是小于它,右子树的结点总是大于它,且结点唯一 [1]。写一个二叉搜索树的结构,最核心的地方就是查找,如果会查找了,俺感觉其他都差不多。二叉树static class TreeNode<...原创 2020-04-24 01:49:01 · 259 阅读 · 0 评论 -
动态规划总结——区间dp(基于LeetCode题目)最长回文子序列
题目汇总这种类型的题目我还没怎么做过。啊有点点难想,找子问题最优嘛,判断最长的回文序列,那我们就找一个区间最大的回文串,然后再加入新的字符,与当前区间的首部判断,如果是,直接在这个区间去首去尾的区间(首部不能重复匹配呀,自然需要上一个小区的最大串。)的最大值+2,如果不匹配,则看去首区间时的最大值大(新增字符可以与小区间内某个字符匹配)还是去尾区域的最大值(不要新增字符)大。那我们得从最小...原创 2020-04-21 22:32:12 · 270 阅读 · 0 评论 -
动态规划总结——线性DP(字符串匹配系列)(基于LeetCode题目)
题目汇总匹配字符串只有仨操作,增删改,这很明显对应三个状态。只要每次选择子串匹配当前子串时最优的操作,即为最终最优的操作了。dp[i][j] word2在i位置时的子串,由word1,j位置子串变成至少需要多少步。状态转移方程:如果i能和j匹配上,很明显直接读上一个word1匹配上一个word2的情况即可。 dp[i][j] = dp[i-1][j-1]如果匹配不上,我们就有三种操作方...原创 2020-04-20 22:06:38 · 244 阅读 · 0 评论 -
动态规划总结——线性DP(买卖股票系列)(基于LeetCode题目)
LeetCode动态规划题目汇总首先解构下问题,要找利益最大,也就是买入和卖出的正差值最大,那么我们需要记录下历史的最低价(截至i天,最低的价格),然后再与每次新的售价进行对比如果更低更新历史最低价,如果比之大则判断是不是大到比最低价之后的最高价还大了(就是差值有没有之前算的大。)dp[i]记录第i天的历史最低价。转移方程:dp[i] = min(dp[i-1],prices[i])然...原创 2020-04-19 03:04:24 · 316 阅读 · 0 评论 -
动态规划总结——线性DP(1)(基于LeetCode题目)
LeetCode dp问题汇总1.线性DPclass Solution { public int longestCommonSubsequence(String text1, String text2) { int[] dp= new int[text1.length()+1]; for(int j=0;j<text2.length();j++)...原创 2020-04-17 18:52:29 · 427 阅读 · 0 评论 -
笔试题目记录01背包
(题意略有改编,题意一致) 法外狂徒张三有n空间的口袋,要去抢口罩,有6箱口罩,第一箱占空间2,里面的口罩价值2k元,第二箱空间为2,价值3k元,3.3空间1k,4.1空间价值5k,5.5空间4k,6.2空间2k。这是一个典型的01背包问题(改一改就是多重背包了),01背包说白了就是个选与不选的问题。在第x个物品时,我们只需知道不选x产品(x-1)个物品该空间(v)的下最大收益情况和选x产品时的...原创 2020-04-14 23:57:50 · 153 阅读 · 0 评论 -
笔试遇到的一道题 求最大单峰序列(动态规划)
题目描述: 给定一个无序数组,找出最大的单峰序列 (就是先升高后降低的序列) 的值,再输出原数组长度除去单峰序列的长度所剩下的元素数量。输入格式: n num1 num2…numn。输出格式: m (原数组长度除去单峰序列的长度所剩下的元素数量)输入样例1: 8 1 2 3 4 5 3 2 1输出样例1: 0输入样例2: 8 5 2 3 8 3 5 1 2输出样例2: 3**思路:...原创 2020-04-09 22:43:48 · 1046 阅读 · 0 评论