
算法学习
主要来自刷leetcode的一些学习记录
Peter Pan_
这个作者很懒,什么都没留下…
展开
-
并查集的应用
在图论的算法题中,虽然最常用的算法是DFS和BFS,但是在求连通分量数量的时候,借助并查集这一数据结构是是十分简单的,以leetcode-547,省份数量 这道题举例。public int findCircleNum(int[][] isConnected) { int size = isConnected.length; UnionFind unionFind = new UnionFind(size); for (int i = 0; i < si原创 2021-11-15 00:03:47 · 458 阅读 · 0 评论 -
力扣-26 树的子结构
class Solution { /** *先通过遍历A,找到与B相等的节点,然后调用递归函数,同左同右 存在三种情况: 1.当最开始A或b都为空肯定是false 2.当遍历B为空且A为空时,说明不满足子数结构条件 3.A与B数值相等,即刻开始判断字树是否配对。 */ public boolean isSubStructure(TreeNode A, TreeNode B) { //1.首先找到第一个点,结合题目设定,原创 2021-11-14 10:40:15 · 451 阅读 · 0 评论 -
位运算_有效的数独
题意描述1. 直接对比法不需要别的思路,按照题意要求,设置三个二维数组,分别代表行、列、以及小单元格,来存储整个数值。例如 rows[i][j] : 即表示在第i行,存在j这个数(因为只是记录存不存在,所以默认0表示不存在,设置rows[i][j] = 1,即表示存在)public boolean isValidSudoku(char[][] board) { int[][] rows = new int[9][9]; int[][] columns = n原创 2021-08-15 11:45:00 · 145 阅读 · 0 评论 -
快慢指针解决环形链表
环形链表双指针的做法,快慢指针的经典题目1. 判断一个链表是否有环设置一快一慢两指针,快指针的步长为2,慢指针的步长为1。如果存在环形链表,那么一定会存在相等的时刻。public boolean hasCycle(ListNode head) { ListNode fast = head; ListNode slow = head; while (fast != null && fast.next != null) {原创 2021-07-23 00:48:15 · 198 阅读 · 0 评论 -
动态规划_花坛种花问题
花坛种花问题新年的第一道每日一题,因为之前找到工作之后想着休息一段时间,算法的练习有所懈怠,希望开年能有一个好运气!题目大意:假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。给你一个整数数组 flowerbed 表示花坛,由若干 0 和 1 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ,能否在不打破种植规则的情况下种入 n 朵花?能则返回 true ,不能则返回 false。输入:flowerbe原创 2021-01-02 10:30:32 · 599 阅读 · 0 评论 -
字符串_字符串排序
题目描述题目描述给定n个字符串,请对n个字符串按照字典序排列。输入描述:输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。输出描述:数据输出n行,输出结果为按照字典序排列的字符串。想法一道华为机考题;如果使用 Java 语言的话,可以重写compare方法即可;记录此题是想解决一直以来对于 comparator中comapre方法重写规则的不了解。借助此题彻底弄清楚。如果返回的值 > 0;那么会将前一个数与后一个进行原创 2020-09-27 17:31:41 · 1745 阅读 · 1 评论 -
栈应用_四则运算
题目输入字符串格式的算术表达式,如: “3+2*{1+2*[-4/(8-6)+7]}”;输出去结果。思路栈的应用;四则运算分为下列四个过程读取字符串 (并不是简单地读入,比如 当字符串中有两位数,例如12时,我们应该读成 “12”而不是“1”,“2”,不然运算会出现错误)。处理字符串,给字符串加0 (为了保证后缀运算的正常运行,需要对出现的负数进行考虑。 例如 (-4 + 3) 为了运算正确,将其处理成(0 - 4 +3))将中缀表达式转化成后缀表达式计算后缀表达式代码public原创 2020-09-01 14:16:15 · 292 阅读 · 0 评论 -
深度优先搜索_能否遍历所有节点
题目给定一个有向图,判断能否从 0 开始,遍历到所有的节点。(总结一下有向图的深度优先遍历)class solution{ boolean[] visit; int num; public boolean canVisitAllRooms(List<List<Integer>> rooms) { int n = rooms.size() //房间的个数 visit = new boolean[n]; num = 0; // 记录访问个数 // 从 0原创 2020-08-31 09:04:25 · 1442 阅读 · 0 评论 -
位运算_范围内的数字与运算
给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。实例:输入: [5,7]输出: 4观察,我们看到对于连续的数字,从末尾往首位看,一定都是0,1 交替;而对于与运算,一旦出现0,那么最终结果结果一定都为0。具体操作,我们从末尾向前遍历m,n的位,同时记录右移清除的位数;相等的时候说明找到了相同前缀;返回恢复的值就可以了。所以此题的意思我们可以转换思想,即求出公共前缀public in原创 2020-08-27 12:42:02 · 500 阅读 · 0 评论 -
深度优先搜索_全排列问题
1 字符串的全排列给定一组字符串,找出所有的排列组合数(有可能存在重复字符)。思路:深度优先搜索,依然是套用搜索算法的模板,但是这里面涉及到重复字符,我们需要排除掉重复的字符串。这就涉及到剪枝问题。上一张图:(借的大佬的)对于如何深度搜索,当我们访问到某个节点时,我们以此节点开始,进行向后查找,我们固定住这个字符,然后重新进入。此时为了避免重复,我们可以用set结构来去重。依然是按照dfs的模板class solution{ // 定义成全局变量,方便dfs的递归 char[] c;原创 2020-08-13 23:23:03 · 566 阅读 · 0 评论 -
深度优先搜索_被围绕的区域
题目给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。示例:X X X XX O O XX X O XX O X X运行你的函数后,矩阵变为:X X X XX X X XX X X XX O X X被围绕的区间不会存在于边界上,换句话说,任何边界上的 'O' 都不会被填充为 'X'。 任何不在边界上,或不与边界上的 'O' 相连的 'O' 最终都会被填充为 'X'。如果两个元素在水平或垂原创 2020-08-11 12:32:43 · 178 阅读 · 0 评论 -
深度优先搜索_有向图的通路
题目叙述节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。输入:n = 3, graph = [[0, 1], [0, 2], [1, 2], [1, 2]], start = 0, target = 2 输出:true思考对于图的搜索,借助邻接表结构,先创建一个邻接表,然后借助dfs。具体见代码注释。 public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {原创 2020-08-04 14:15:21 · 981 阅读 · 0 评论 -
深度优先搜索_课程表问题
题目叙述必须选修 numCourse 门课程,记为 0 到 numCourse-1 。在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?实例:输入: 2, [[1,0],[0,1]]输出: false解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。思考个人错误的思考原创 2020-08-04 10:34:48 · 250 阅读 · 0 评论 -
位运算_异或_消失的数字
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数借助异或的性质:A^A = 0;A^0 = A;A ^ B ^ B = A;数组中有的数字一定会和数组的索引构成一对重复数字,由性质3 最终会消掉。其中,N 可以和数组的长度构成一对重复,因此最终还要异或一下数组的长度,然后借助性质2,我们将初始值设置为0;那么一个循环下来,最后的结果就是那个消失的数。public int missingNumber(int[] nums) { int res = 0; for(原创 2020-07-29 09:26:19 · 260 阅读 · 0 评论 -
单调队列_滑动窗口的最大值
给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。例如滑动窗口的位置 最大值--------------- -----[1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [原创 2020-07-26 17:47:29 · 206 阅读 · 0 评论 -
双指针_移动零
给定一个数组,将不为0的数字移动到数组左端,0移动到数组右端。public void moveZeroes(int[] nums) { // i 用来记录不为0的位置 int i = 0; for(int j=0; j<nums.length; j++){ if(nums[j] != 0){ nums[i++] = nums[j]; } } // 此时i原创 2020-07-21 16:19:29 · 242 阅读 · 0 评论 -
栈应用_最小栈
单调栈的应用,维护一个栈顶为最小值得栈;当然若要求最大值,反之class MinStack{ private static Stack<Integer> stack; // 维护的最小栈 private static Stack<Integer> minStack; public MinStack(){ stack = new Stack<>(); minStack = new Stack<>(); } // push publ原创 2020-07-19 21:49:44 · 149 阅读 · 0 评论 -
栈应用_每日温度
题目描述:请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]思考:本题需要找出右边第一个更大的数;因此我们可以维护一个单调栈。public int[] dailyTemperatures(int[] T) { in原创 2020-07-16 16:24:01 · 154 阅读 · 0 评论 -
排序_排序算法整理
经常零零散散的用到排序算法,将几类常见的总结下来:插入排序/** * 时间复杂度O(n^2),空间复杂度O(1) * 稳定排序 * @param arr */ public static void inserSort(int[] arr) { int i,j; for(i=1;i<arr.length;i++){ int tmp = arr[i];原创 2020-07-14 15:30:28 · 101 阅读 · 0 评论 -
递归_递归与回溯
递归和回溯递归一般套路1.判断当前情况是否非法,。例如,看看当前处理的情况是否越界,是否出现了不满足条件的情况。通常,这一部分代码都是写在最前面的。2.判断是否满足结束递归的条件。3.将问题的规模缩小,递归调用。4.利用在小规模问题中的答案,结合当前的数据进行整合,得出最终的答案。代码实现function fn(n) { // 第一步:判断输入或者状态是否非法? i...原创 2020-02-21 17:57:19 · 254 阅读 · 0 评论 -
递归_斐波那契的改进
斐波那契数列的改进求法最初的斐波那契数列:public int fib(n){ if(n == 0){ return 0; } if(n == 1){ return 1; } return fib(n-1)+fib(n-2); }可以看出,当数字很小的时候还好,但是一旦数字变大,那么在递...原创 2020-02-22 15:48:05 · 434 阅读 · 0 评论 -
二叉树_重建二叉树
描述题目给定两个数组,一个是前序遍历数组 preorder[ ],一个是中序遍历数组 inorder[ ];要求输出还原二叉树;思考核心在于我们要理解前序和中序便利的特点前序遍历:根节点-左节点-右节点中序遍历:左节点-根节点-右节点;所以我们从二叉树的根节点开始重构;也就是preorder的第一个值;同时用一个map存储它在中序数组中的索引值;从而可以将中序数组以索引下表为中点 划分为两块,左边为左子树,右边为右子树;然后递归,代码演示public class TreeNode {原创 2020-06-17 11:06:55 · 143 阅读 · 0 评论 -
栈的应用_判断一个整数序列是否是二叉搜索树的后序遍历结果
单调栈思路首先考虑一个后续遍历(left-right-root),如果将其逆置,则变为(root-right-left); 又因为该树是一个二叉搜索树,则right > root;也就是说 按照这个逆置的顺序遍历下去一定是逐渐变大的,然后在某个点会变小,则说明此时这个点进入了左子树。为什么要用单调栈呢,因为往右子树遍历的过程,value是越来越大的,一旦出现了value小于栈顶元素val...原创 2020-03-28 17:38:30 · 167 阅读 · 0 评论 -
图的搜索_机器人运动范围
机器人运动范围问题问题描述:地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8...原创 2020-03-28 16:29:29 · 209 阅读 · 0 评论 -
动态规划_连续子数组的最大和
class Solution { /** 动态规划 拆解成子问题,dp[i]表示当前nums数组以i下标结尾的最大连续数组之和 */ public int maxSubArray(int[] nums) { int max = nums[0]; for(int i=1;i<nums.length;i++){ ...原创 2020-03-19 15:41:27 · 126 阅读 · 0 评论 -
动态规划_数学分析_剪绳子问题1
剪绳子问题1数学分析当n=2, 1+1;当n=3, 2+1 21=2;当n=4, 22>31;当n=5, 32>41;当n=6, 33>4*2;综上算法流程:当 n \leq 3n≤3 时,按照贪心规则应直接保留原数字,但由于题目要求必须剪成 m>1m>1 段,因此必须剪出一段长度为 11 的绳子,即返回 n - 1n−1 。当 n&...原创 2020-03-27 16:33:56 · 514 阅读 · 0 评论 -
动态规划_将一个数字翻译成字符串
问题描述给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法求解思路这是一道典型的动态规划问题,分解求解,当然是要找出转移状态方程。先将数字转化为字符串,方便后续逐个处理。dp[i] 存放长度为i的数字有多少种翻译...原创 2020-04-02 19:02:03 · 227 阅读 · 0 评论 -
动态规划_除数博弈问题
题目描述:黑板上有一个数字 N 。在每个玩家的回合,玩家A,B需要执行以下操作:A选出任一 x,满足 0 < x < N 且 N % x == 0 。用 N - x 替换黑板上的数字 N 。如果玩家无法执行这些操作,就会输掉游戏。永远都是A先手,只有在A在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。思考1.dp数组设定 dp...原创 2020-05-07 20:30:36 · 226 阅读 · 0 评论 -
动态规划_机器人礼物价值
问题描述在二维迷宫中,每一个格子都有包含固定价值的礼物;机器人从 [0][0] 出发,走到右下角,每次只能向右 或向下走,走到一个格子可收获该格子中的礼物;问走到最右下角,可收获的最大礼物价值是多少?动态规划思考dp[i][j] 的定义:存储 到达 [i][j] 的 的格子点时可获得礼物的最大价值。考虑机器人的走法,所以对于第一列和第一行 :dp[i][j] += dp[i][j-1],dp[i][j] += dp[i-1][j]。对于其余的格子,dp[i][j] += max( dp[i-1]原创 2020-05-09 18:04:32 · 194 阅读 · 0 评论 -
动态规划_机器人不同路径
不同路径-version 1题目均来自leetcode问题描述:一个机器人位于一个 m x n 网格的左上角 。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角问总共有多少条不同的路径?动态规划思想:首先依然是要定义状态dp。我们设置 dp[i][j] : 存放着到达该点的不同路径的总数。思考转移方程:首先考虑第一行 与 第一列,因为只能向右或者向下,因此第一行的点只能由它左边的点到达;同理,第一列的点只能由它上面的点到达。因此 dp[i][0] 和 dp[0][j] 均原创 2020-05-11 20:57:43 · 380 阅读 · 0 评论 -
动态规划_机器人迷路
问题描述在一个二维数组迷宫中,机器人从左上角出发,每次只能向右或者向下;判断是否能到达最右下角;若可以,返回其中一条可行的路径。动态规划思考原创 2020-05-11 21:43:21 · 463 阅读 · 0 评论 -
深度优先搜索_矩阵中的字符路径问题
矩阵中的字符路径请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。[[“a”,“b”,“c”,“e”],[“s”,“f”,“c”,“s”],[“a”,“d”,“e”,“e”]]但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵原创 2020-06-04 21:42:16 · 219 阅读 · 0 评论 -
栈应用_有效的括号
题目:给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。。这一题是借助栈先进后出的特性。public boolean isValid(String s) { // 奇数肯定false; if(s.length()%2 == 1) return false; if(s.isEmpty()) return true; char[] string = s.toCharArray(); Stack<Character> stack = ne原创 2020-07-13 22:50:09 · 118 阅读 · 0 评论 -
位运算_汉明距离
1最开始的思路:将x,y都右移一位计算异或值。public int hammingDistance(int x, int y) { int res=0; // 当x , y 都不为0时可以继续 while(x!=0 || y!=0){ // 计算最右边的值 int tmp_x = x&1; int tmp_y = y&1; if((tmp_x ^ tm原创 2020-07-13 21:55:49 · 201 阅读 · 0 评论 -
位运算_异或的性质
位运算-异或的总结1 异或^ 的性质两个数异或,相同的位数等于0 ;0110 ^ 1100 = 1010一个数与0异或,结果等于本身;一个数异或本身,结果为0;综上,可得第四条性质: a ^ b ^ b = a;2.三道典型的题目2.1 一个数组,除了某一个数字以外,其他的都出现了两次,找出这个数字。显然,这题借助Map可以找出;但是我们借助 异或 的性质,可以大大提高效率。**遍历数组,将所有的数字异或,最终的结果即为答案;(性质 4) public int singleNum原创 2020-06-04 08:39:09 · 1162 阅读 · 0 评论 -
栈应用_判断出栈序列是否符合出栈规则
问题描述输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等( 本题源自leetcode-946)。思路不如我们就初始化一个栈,按照出栈序列和入栈序列手动还原一遍。如果出栈序列是正确的,那么最后栈肯定是空的。1 设置变量i,j分别指向入栈和出栈序列2 遍历入栈序列,这之中判断,如果栈顶元素等于出栈序列当前元素,则出栈,直到不相...原创 2020-04-03 11:30:52 · 390 阅读 · 0 评论 -
leetcode-分糖果(2)
分析妹妹要满足两个条件:第一 糖果种类数目不能比哥哥少;第二 两人分到的糖果数量要一样。所以考虑极端情况: 当糖果种类最多(即每种一个),妹妹也只能得到一半的糖果种类数(条件2限制);糖果数量最少,就是一种糖果,妹妹获得一种糖果,糖果总量一般。所以我们为了保证种类,分法:先每种糖果给妹妹一个,如果达到数目的一半,不管后面还有没有新种类,妹妹也只能得到一半。 如果发了几颗就已经开始重复(还没有...原创 2020-03-20 10:15:09 · 403 阅读 · 0 评论