算法与数据结构
文章平均质量分 74
暗夜猎手-大魔王
热爱运动,喜欢跑步
展开
-
一致性哈希算法
有一堆待执行的任务(N个) 有一机器集群(M个),怎样分配任务最佳,使得每台机器分到的任务数尽量均衡,当机器集群数量发生变化时,任务数还是尽量平均分配,并且对于已分配的任务尽量减少再次分配,减少任务移动的成本。直接哈希取余算法选择任务的某一特征值,哈希取余来分配任务,第i个任务的特征为hash(i) 则其应该分配到机器编号为 hash(i)%M优点:分配方式简单缺点:特征值和哈希算法的选择非常重要,否则任务会分配不均衡,极端情况会分配到同一台机器;当机器的数量发生变...原创 2022-01-29 19:56:17 · 1056 阅读 · 0 评论 -
常用算法思路总结
最近将剑指 Offer(专项突击版)刷了一遍,总结一下,最好结合图书来看,书里有很多总结,书中解法很经典,leetcode地址:力扣常见的算法方法 二分查找 双指针 滑动窗口 堆 优先级队列 单调栈 前缀树 字典树 前缀和+哈希 排序 快速排序 归并排序 并查集 拓扑排序 回溯法 ...原创 2021-12-25 18:48:52 · 693 阅读 · 0 评论 -
滑动窗口--方向相同的双指针思路
大致思路如下: 给定一个序列,定义两个指针left,right,根据题意定义区间[left,right]之前的衡量指标f,比如区间和,乘积以及其他等。开始时left=right=0,计算指标f,left先不变,right往右边移动,更新f的值,当f符合一定条件时,left往右边移动,此时相当于区间变小,更新f的值,如果f一直符合题意,则left一直往右移动,如果f不符合题意,则left不变,继续移动right位置。如此往复,相当于一个滑动窗口把整个序列遍历了一遍,在整个过程中,当找到区间[...原创 2021-12-20 19:52:57 · 164 阅读 · 0 评论 -
算法--岛屿问题(DFS/BFS/UF)
与岛屿有关的问题1.岛屿数量https://leetcode-cn.com/problems/number-of-islands/2.岛屿的最大面积https://leetcode-cn.com/problems/max-area-of-island/3.岛屿周长https://leetcode-cn.com/problems/island-perimeter/4.不同岛屿的数量https://leetcode-cn.com/problems/number-of-distin原创 2021-07-14 22:22:15 · 5727 阅读 · 0 评论 -
算法--拓扑排序
拓扑排序无向图和有向图 有向图又分为有向无环图DAG和有向有环图 给定一个包含 n个节点的有向图 G,我们给出它的节点编号的一种排列,如果满足:对于图 G中的任意一条有向边 (u, v),u在排列中都出现在 v的前面。那么称该排列是图 G的「拓扑排序」易知 有向有环图必定没有拓扑排序 有向无环图可能有多条拓扑排序路径。任何 DAG 具有至少一个拓扑排序,存在算法用于在线性时间内构建任何 DAG 的拓扑排序1.课程表https://leetcod...原创 2021-07-11 20:41:01 · 344 阅读 · 1 评论 -
算法--回溯+剪枝2(二维数组)
之前学习了一维数组的回溯算法 现在学习一下二维数组的回溯算法,基本套路差不多,先复习一下回溯算法基本套路定义结果集result 定义搜索路径path 给定待搜索集合nums 记录当前搜索位置index如果满足停止条件 将path加入到结果集result中 返回;遍历当前位置可选子节点列表: 将子节点加入path 改变相应变量; 递归子节点; 回溯 将子节点从path中移除 回溯相应变量;给定待搜索的集合 一般为一位数...原创 2021-07-11 11:01:25 · 396 阅读 · 2 评论 -
算法--回溯+剪枝
搞了一天的回溯算法,现在总结一下,基本的解题思路还是有一定套路的。回溯算法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:找到一个可能存在的正确的答案;在尝试了所有可能的分步方法后宣告该问题没有答案。 回溯算法本质上是一种递归算法,基本上...原创 2021-07-10 18:14:30 · 1599 阅读 · 0 评论 -
算法--字典树
字典树主要用于大量具有相同前缀的字符串存储与检索。字符串的前缀匹配字典树数据结构:对于每一个节点,都有一个叶子节点数组,如果字符串都是小写字母,一般叶子节点数组为26,利用字符的索引来快速定位叶子节点数组位置。常见的基本操作 插入 查找 前缀查找:插入:每遍历字符串中的一个字母,若该字母没有出现过,则就在对应的空位置往下生成一个 TrieTrie;若该字母出现过,则直接继续遍历下一个字母,直到字符串遍历结束(注意:结束时要标记为 endend,表示这个单词已经结束了)。查找:遍历要...原创 2021-07-06 22:48:08 · 366 阅读 · 2 评论 -
算法--前缀和+哈希表
今天学习一下前缀和和哈希表算法思想。主要用于解决连续子数组问题。前缀和:给定一个数组a[0,..n-1] 定义Sn=a0+a1+...+an-1。则连续子数组和Suma[i, j] 可以表示为ai+...+aj=Sj-Si-1。即连续子数组和问题可以转换为两个前缀和差。1.和为K的子数组https://leetcode-cn.com/problems/subarray-sum-equals-k/给定一个整数数组和一个整数k,你需要找到该数组中和为k的连续的子数组的个数。想要...原创 2021-07-04 11:47:28 · 1627 阅读 · 0 评论 -
算法--打家劫舍--动态规划
1.打家劫舍Ihttps://leetcode-cn.com/problems/house-robber/你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。房屋数组nums[], dp[i]表示到第i个房子偷盗的最大金额如果只有一个房子 则直接偷盗原创 2021-06-16 22:49:45 · 328 阅读 · 0 评论 -
算法--最短的桥DFS+BFS
在给定的二维二进制数组A中,存在两座岛。(岛是由四面相连的 0 形成的一个最大组。)现在,我们可以将0变为1,以使两座岛连接起来,变成一座岛。返回必须翻转的0 的最小数目。首先找到这两座岛,随后选择一座,将它不断向外延伸一圈,直到到达了另一座岛。在寻找这两座岛时,我们使用深度优先搜索。在向外延伸时,我们使用广度优先搜索。对数组 A 中的 1 进行深度优先搜索,可以得到两座岛的位置集合,分别为 source 和 target。随后我们从 source 中的所有位置开始进行广度优先搜...原创 2021-04-18 17:51:00 · 388 阅读 · 0 评论 -
算法--被围绕的区域--BFS/DFS/UF
给你一个 m x n 的矩阵 board ,由若干字符 'X' 和 'O' ,找到所有被 'X' 围绕的区域,并将这些区域里所有的'O' 用 'X' 填充。示例 1:输入:board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]]输出:[["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]]解释:被围.原创 2021-04-05 12:03:14 · 328 阅读 · 0 评论 -
算法BFS--单词拆分
https://leetcode-cn.com/problems/word-break/给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定s 是否可以被空格拆分为一个或多个在字典中出现的单词。说明:拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。可以采用DFS BFS或者DP来解决 无论采用何种方式,都类似于一种搜索问题。依次遍历给定字符串的每一个字符串 假定当前遍历位置序号为i,则字符串S此时可以分为两部分s0=s[0, i-1],s1=s[i,...原创 2021-03-28 12:46:25 · 389 阅读 · 0 评论 -
算法--单词接龙(BFS)
字典wordList 中从单词 beginWord和 endWord 的 转换序列 是一个按下述规格形成的序列:序列中第一个单词是 beginWord 。序列中最后一个单词是 endWord 。每次转换只能改变一个字母。转换过程中的中间单词必须是字典wordList 中的单词。给你两个单词 beginWord和 endWord 和一个字典 wordList ,找到从beginWord 到endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。htt...原创 2021-03-21 11:59:38 · 653 阅读 · 0 评论 -
算法--滑动窗口
1.尽可能使字符串相等https://leetcode-cn.com/problems/get-equal-substrings-within-budget/给你两个长度相同的字符串,s 和 t。将 s中的第i个字符变到t中的第 i 个字符需要|s[i] - t[i]|的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。用于变更字符串的最大预算是maxCost。在转化字符串时,总开销应当小于等于该预算,这也意味着字符串的转化可能是不完全的。如果你可...原创 2021-03-14 18:18:09 · 240 阅读 · 0 评论 -
算法----LFU缓存
实现最不经常使用(LFU)缓存算法设计并实现数据结构。它应该支持以下操作:get和put。get(key)- 如果键存在于缓存中,则获取键的值(总是正数),否则返回 -1。put(key, value)- 如果键不存在,请设置或插入值。当缓存达到其容量时,则应该在插入新项之前,使最不经常使用的项无效。在此问题中,当存在平局(即两个或更多个键具有相同使用频率)时,应该去除 最近 ...原创 2020-04-06 09:57:07 · 1240 阅读 · 0 评论 -
算法----盛最多水的容器
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点(i,ai) 。在坐标内画 n 条垂直线,垂直线 i的两个端点分别为(i,ai) 和 (i, 0)。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器,且n的值至少为 2。图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(...原创 2020-03-30 21:01:32 · 339 阅读 · 0 评论 -
算法----单词的压缩编码
来道算法题,压压惊。给定一个单词列表,我们将这个列表编码成一个索引字符串S与一个索引列表 A。例如,如果这个列表是 ["time", "me", "bell"],我们就可以将其表示为 S = "time#bell#" 和 indexes = [0, 2, 5]。对于每一个索引,我们可以通过从字符串 S中索引的位置开始读取字符串,直到 "#" 结束,来恢复我们之前的单词列表。那...原创 2020-03-28 17:05:56 · 838 阅读 · 0 评论 -
算法4--分奇偶行打印二叉树--队列的应用
头条的一道面试题,层序打印二叉树,奇数行时从左到右,偶数行时从右到左。如上所示,打印结果为 : 1 3 2 4 5 6 7 10 9 81. 普通的层序打印二叉树,一般采用一个队列,根节点入队列,然后一次遍历队列中的节点,打印每一个节点值,同时若该节点左右节点非空,继续入队列:public static void levelOrder...原创 2018-10-22 09:04:47 · 570 阅读 · 0 评论 -
算法5--快速排序递归和非递归实现方式--排序
快速排序主要思想,选取一个基准,进行一趟排序,调整数组使基准左边的数都小于基准,使基准右边的数都大于基准。然后对于基准划分的两个子数组依次进行递归划分调整。1.递归版本public static void quickSort(int[] arr, int lo, int hi){ if(lo>=hi) return; int q = partition(arr, lo, h...原创 2018-10-22 10:29:32 · 256 阅读 · 0 评论 -
算法1--去除字符串的“ac”,"b"连串--栈的应用
之前去美团和滴滴面试都遇见了这道题,当时思路还不是很清晰,后来又想了一下。public class Study { public static void main(String[] args) { System.out.println(removeSpecialChar("bbdfg")); System.out.println(removeSpecialChar("ghgha...原创 2018-10-20 11:28:31 · 1045 阅读 · 0 评论 -
算法2--输出数组中每个元素以及后面第一个比它大的二元组序列--栈的应用
去宜信面试一道面试题输出数组中每个元素以及后面第一个比它大的元素二元组,若没有则输出-1,不必按数组顺序输出。例如[7,2,3,8,6,9,1],则输出(7,8),(2,3),(3,8),(8,9),(6,9),(9,-1),(1,-1).输出顺序不要求。public class Study2 { public static void main(String[] args)...原创 2018-10-20 11:44:09 · 604 阅读 · 0 评论 -
算法3--设计调度算法使规定时间内执行任务最多--贪心策略
给定开始时间start和结束结束时间end,给定一组任务列表(t1, t2)表示每个任务的起始时间和结束时间。其中每个任务必须按照规定时间执行,不能有重合,设计一个调度算法,使start到end时间内执行任务个数最多。 可以使用贪心策略,先选取第一个任务,第一个任务应该具有什么特征才能使总任务数最多。第一次,想的是任务的起始时间最小的,尽管起始时间可能最小,然而可能任务...原创 2018-10-20 15:16:45 · 2758 阅读 · 0 评论 -
设计模式--单例模式
设计单例模式:单例设计模式主要有两点:1.延迟初始化,当具体使用时,才实例化对象2.多线程安全 多线程情况下保证对象是单例的具体实现方式主要有以下两种:1.双重检查加锁机制public class Singleton { private static volatile Singleton s; //私有构造方法 private Singleton(){} //双...原创 2018-10-20 18:51:51 · 123 阅读 · 0 评论 -
算法6--SumK问题
整理总结一下与sumK有关的问题。1.两数之和给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。示例:给定 nums = [2, 7, 11, 15], target = 9因为 nums[0] + nums[1] = 2 + 7 = 9所以返回 [0, 1]使用一个map用来存储数组元素值以及下...原创 2018-10-28 15:08:23 · 604 阅读 · 0 评论 -
算法8--字符串
1.实现一个函数,将字符串的每个空格替换为“%20” 在原来字符串上替换 空间足够如果从前往后,当遇见空格时,要替换成%20时,势必要移动后面所有字符。可以考虑从后往前来处理替换之后字符与原字符的关系,首先计算原来字符串中空格数量,由于一个空格替换成3个字符,因此字符串长度要变为length + 2 * numSpace从后往前,当遇见非空格时,直接对应放入,当遇空格时,j指针要移动三...原创 2018-10-31 21:00:12 · 117 阅读 · 0 评论 -
算法9--链表操作
1.从尾到头打印单链表利用栈先遍历一遍链表,然后依次从栈顶弹出即可。public static void printList(ListNode head){ Stack<Integer> s = new Stack<>(); ListNode node = head; while(node!=null){ s.push(node.val); ...原创 2018-10-31 21:13:49 · 181 阅读 · 0 评论 -
算法7--数组查找
1.长度为n的数组,元素大小为0-n-1,有些数字重复,找出任意一个重复数字。例如{2, 3, 1,0, 2, 5, 3} 对应输出2或3. 由于数字长度为n,数字大小为0到n-1,可以将数字i放置在数组中i位置,若数组中i位置上数字已经是i,则说明i数字重复了,否则则进行交换,将数字i放置在数组中i位置。public static int findNum(int[] a...原创 2018-10-30 12:00:06 · 244 阅读 · 0 评论 -
算法10--二叉树
1.给定二叉树的前序和中序遍历数组,重新构建二叉树int[] pre = new int[]{1,2,4,7,3,5,6,8};int[] in = new int[]{4,7,2,1,5,3,8,6};假设前序数组pre 起始坐标ps,pe 中序数组in is,ie前序数组的第一个元素即为根节点rootValue = 1寻找根节点在中序数组中的位置索引rootInI...原创 2018-11-01 17:17:18 · 144 阅读 · 0 评论 -
算法13--旋转数组二分查找
旋转数组 将一个有序数组前一部分移到后端 例如 12345---345121.求旋转数组的最小值数组基本有序可以考虑二分查找来解决,考虑旋转数组的特点前半部分递增后半部分递减,使用两个指针,第一个index1指向递增部分,第二个index2指向递减部分,不断逼近,当两者距离之差index2-index1等于1,可以得到最小值为第二个指针index2位置的数值。求出中点值 mid...原创 2018-11-03 12:02:20 · 1384 阅读 · 0 评论 -
算法11--栈与队列
1.两个栈实现一个队列栈1用于不断接受新元素,栈2作为中间容器,当需要出队列时,将栈1元素全部转移到栈2,只保留一个,然后弹出,当弹出之后再把栈2元素全部放入到栈1中,保持原来的倒序顺序 Stack<Integer> s1 = new Stack<>(); Stack<Integer> s2 = new Stack<>(); ...原创 2018-11-01 17:36:48 · 137 阅读 · 0 评论 -
算法16--单链表翻转
今天去腾讯面试了,一共五道算法题,整理一下。1.反转单链表2.二叉树中序遍历非递归3.合并两个字典4.最长的01个数相等的连串5.长度为2N的数组,划分为相等两部分,使其之和的差的绝对值最小反转单链表 递归与非递归方式:非递归方式 非递归从第一个节点开始翻转链表可以采用双指针与三指针来实现三指针: pPre pCur pNext 分别为当前指针的前...原创 2018-11-09 20:46:37 · 229 阅读 · 0 评论 -
算法17--二叉树中序遍历非递归实现
1.二叉树的中序遍历首先看一下递归方式的实现方式:class TreeNode: left = None right = None var = 0 def __init__(self, var): self.var = var def inOrder(root): if root == None: ...原创 2018-11-09 21:50:13 · 1570 阅读 · 0 评论 -
算法12--topK求一个数组中第k大的数
求一个数组中第k大的值解法一:建立一个k个元素的最大堆,首先将数组中前k个元素放入堆中,此时堆顶元素为第k大的元素,后面继续遍历数组,比较堆顶元素与数组中元素值,当数组中元素小于堆顶元素时,将堆顶元素弹出,新元素入堆,这样最终堆顶元素即为第k大。可以直接利用Java中优先级队列,这里传入一个比较器来构造最大堆。public static int topK3(int[] arr, ...原创 2018-11-02 16:58:12 · 5816 阅读 · 2 评论 -
算法15--外部排序
一道面试题:4G内存, 100G文件,文件中存放字符串,排序这100G文件字符串数据内部排序:内存中可以存放所有待排序的数据,可以使用高效的内部排序来完成例如快速排序,归并排序,堆排序等。外部排序:待排序数据过大,内存不能一次全部加载来完成排序。一般采用分段加载内部排序,然后多路合并,产生最后排序结果。1. 基本实现方式: 将100G文件分成100份排号为1,2....原创 2018-11-07 11:20:55 · 943 阅读 · 0 评论 -
算法14--归并排序
今天去面试,让写一下归并排序,好久没有写排序了,有点忘了。归并排序采用分治策略,时间复杂度为O(NlogN) 空间复杂度O(N) 给定一个数组,从中间值划分为两部分,假定这两部分是有序的,则执行一个合并过程,将两个有序的数组合并成一个数组。以此类推,划分为的两个子数组是上述过程的子问题,因此可以递归解决。递归的最后一层为子数组的元素个数只有一个,即有序。然后合并两个单元...原创 2018-11-07 09:44:46 · 267 阅读 · 2 评论 -
算法22--全组合
给定一个数组,输出其全组合 例如 123 输出 1,2,3,12,13,23,123解法一:对于N位数据,考虑每一位对于组合结果的影响,对于每一位可以选择取或者不取。一共有power(2,n)中取法,当全部不取时,对于最后结果没有意义,因此最终取法共有power(2,n)-1.可以利用二进制数字从1变为N,刚好变化过程中的二进制01分别对应每一位的取值情况,输出每一种情况即可。...原创 2018-11-13 16:02:20 · 2441 阅读 · 0 评论 -
算法18--合并两个字典
将字典y合并到字典x中,若x中没有y中的key则x执行添加操作,若x中已有对应key则执行更新操作merge(dict x , dict y)若y==none 则直接返回x即可若x==none,则将x复制y返回若y!=none and x!=none ,则取出x keys以及y keys 遍历y的每一个key: 若ykey在xkeys中不存在,则在x中添加相应yke...原创 2018-11-11 11:33:48 · 800 阅读 · 0 评论 -
算法19--求01数组中连续的01长度相等的最长子数组索引
给定一个01数组,例如0100001000011111000011100001010010010100 求该数组中01数字个数相等的最长连续子数组的索引。解法1:常规解法遍历所有可能,统计连续子数组中0,1个数相等的最长子数组。 时间复杂度为O(N3)def maxSubArray(num): max = 0 lo = 0 hi = 0 #range(a...原创 2018-11-11 16:34:26 · 1285 阅读 · 0 评论 -
算法23--最长公共子序列以及子串
问题1:给定两个字符串,求其最大公共子序列例如asbcdfg和scdfgjkl, 则返回scdfg使用动态规划求解,假设s1=<x1,x2....xn> s2=<y1,y2..ym>令f[i][j]表示串s1以索引i结尾,串s2以索引j结尾的最长公共子序列的长度。当i==0或者j==0时,此时s1[i] s2[j]均为空,即有f[i][j]=0i...原创 2018-11-13 17:39:25 · 197 阅读 · 0 评论