算法
文章平均质量分 54
acmug
Go to bed early, get up early, knock code
展开
-
力扣教我学置换环算法
置换环原创 2022-11-14 16:30:05 · 850 阅读 · 1 评论 -
力扣教我学线段树
线段树转载 2022-10-07 08:29:47 · 213 阅读 · 0 评论 -
力扣教我学前缀树
Trie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:指向子节点的指针数组 children。对于本题而言,数组长度为 26,即小写英文字母的数量。此时 children[0] 对应小写字母 a,children[1] 对应小写字母 b,…,children[25] 对应小写字母 z。布尔字段 isEnd,表示该节点是否为字符串的结尾。插入字符串我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:子节点存在。沿着指针移动到子节点,继续处理下一个字符。子节点不存在原创 2021-10-19 11:26:39 · 58 阅读 · 0 评论 -
Java全排列
public class FullPermutation { private static List<String> ans = new LinkedList<>(); private static List<Character> res = new LinkedList<>(); public static void main(String[] args) { String s = "bba";原创 2021-05-23 11:02:50 · 45 阅读 · 0 评论 -
LeetCode35搜索插入位置
题目描述给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。示例 1:输入: [1,3,5,6], 5输出: 2示例 2:输入: [1,3,5,6], 2输出: 1示例 3:输入: [1,3,5,6], 7输出: 4示例 4:输入: [1,3,5,6], 0输出: 0使用二分查找,世间复杂度o(nlogn)class Solution { public int原创 2020-11-27 15:17:57 · 109 阅读 · 0 评论 -
Java版KMP
Next数组回溯其实用到了公共前后缀匹配的思想。下面J值的回溯就是用到了前缀匹配的思想,T!=C,但是T前面和C前面的G相等,所以利用前缀匹配的思想,将J回溯。所以才有J = Next[J];// KMP算法主体逻辑。str是主串,pattern是模式串public static int kmp(String str, String pattern) { //预处理,生成next数组 int[] next = getNexts(pattern); int j = 0;原创 2020-11-06 16:05:07 · 113 阅读 · 0 评论 -
快排Java
public static void quickSort(int array[], int left, int right) { if (left >= right) { return; } int i = left; int j = right; int key = array[left]; while (i < j) { while (i < j && array[j] > key) { j--; } arr原创 2020-11-02 22:22:35 · 59 阅读 · 0 评论 -
二叉搜索树与双向链表
排序链表: 节点应从小到大排序,因此应使用 中序遍历 “从小到大”访问树的节点;双向链表: 在构建相邻节点(设前驱节点 pre ,当前节点 cur )关系时,不仅应 pre.right = cur ,也应 cur.left = pre 。循环链表: 设链表头节点 head 和尾节点 tail ,则应构建 head.left = tail 和 tail.right = head 。class Solution { Node pre, head; public Node treeToDou原创 2020-10-27 12:40:03 · 95 阅读 · 0 评论 -
LeetCode84柱状图中最大矩阵
原始代码我们枚举「高」,我们可以使用一重循环枚举某一根柱子,将其固定为矩形的高度 h。随后我们从这跟柱子开始向两侧延伸,直到遇到高度小于 h 的柱子,就确定了矩形的左右边界。如果左右边界之间的宽度为 w,那么对应的面积为 w * h。class Solution {public: int largestRectangleArea(vector<int>& heights) { int n = heights.size(); int an原创 2020-10-22 15:30:09 · 92 阅读 · 0 评论 -
二维平面使用回溯法DFS
怎么表示上下左右int [][]dirs={{-1,0},{1,0},{0,-1},{0,1}};题目描述给定一个二维网格和一个单词,找出该单词是否存在于网格中。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。回溯法DFSclass Solution { char [][]board; int m; int n; int [][]dirs={{-1,0},{1,0},{原创 2020-10-21 16:44:37 · 122 阅读 · 0 评论 -
LeetCode68文本左右对齐
1.先取出一行能够容纳的单词,将这些单词根据规则填入一行2.计算出额外空格的数量 spaceCount,额外空格就是正常书写用不到的空格 2.1除去所有单词的长度3.平均分布:简单来说就是商和余数的计算4.特殊处理 4.1一行只有一个单词,单词左对齐,右侧填满空格 4.2最后一行,所有单词左对齐,中间只有一个空格,最后一个单词右侧填满空格需要填充的空格数量就是词尾空格 + 额外空格,当然最后一个单词的词尾空格不算。具体计算请看下面代码展示。class Solution { pu原创 2020-10-18 10:50:45 · 87 阅读 · 0 评论 -
折木棍
题目描述在你的面前从左到右摆放着n根长短不一的木棍,你每次可以折断一根木棍,并将折断后得到的两根木棍一左一右放在原来的位置(即若原木棍有左邻居,则两根新木棍必须放在左邻居的右边,若原木棍有右邻居,新木棍必须放在右邻居的左边,所有木棍保持左右排列)。折断后的两根木棍的长度必须为整数,且它们之和等于折断前的木棍长度。你希望最终从左到右的木棍长度单调不减,那么你需要折断多少次呢?用例输入:[3,5,13,9,12]输出:1输入:[3,12,13,9,12]输出:2输入:[3,13,12,9,12原创 2020-10-17 19:06:12 · 293 阅读 · 0 评论 -
加一
注意坑根据题意加一,没错就是加一这很重要,因为它是只加一的所以有可能的情况就只有两种: 除 99 之外的数字加一; 数字 99。加一得十进一位个位数为 0 加法运算如不出现进位就运算结束了且进位只会是一。所以只需要判断有没有进位并模拟出它的进位方式,如十位数加 1 个位数置为 0,如此循环直到判断没有再进位就退出循环返回结果。然后还有一些特殊情况就是当出现 99、999 之类的数字时,循环到最后也需要进位,出现这种情况时需要手动将它进一位。class Solution { publi原创 2020-10-16 09:47:16 · 70 阅读 · 0 评论 -
0-1背包问题
明确选择和状态初始化,容量为0,物品可供选择为0,总价值为0选择就是每个珠宝是否选择。状态就是dp数组,含义是对于dp[i][j] 放第i件物品对于容量j的最大价值为dp[i][j]。for循环规则,i是 0-m j是 0-npublic class Solution{ int[] vs = {0,2,4,3,7}; int[] ws = {0,2,3,5,5}; Integer[][] results = new Integer[5][11]; @Te原创 2020-10-16 09:07:12 · 127 阅读 · 1 评论 -
LeetCode62不同路径
LeetCode62不同路径一个机器人位于一个 m x n 网格的左上角,机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角问总共有多少条不同的路径?典型的动态规划我们令 dp[i][j] 是到达 i, j 最多路径动态方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]注意,对于第一行 dp[0][j],或者第一列 dp[i][0],由于都是在边界,所以只能为 1class Solution { public int uniquePaths(in原创 2020-10-15 17:58:01 · 98 阅读 · 0 评论 -
康托展开和逆康托展开
简述康托展开是一个全排列到一个自然数的双射,常用于构建hash表时的空间压缩。设有n个数(1,2,3,4,…,n),可以有组成不同(n!种)的排列组合,康托展开表示的就是在n个不同元素的全排列中, 比当前排列组合小的个数,那么也可以表示当前排列组合在n个不同元素的全排列中的名次(当前的名次 = 比当前排列组合小的个数 + 1)。原理X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!其中, a[i]为整数,并且0 <= a[i] &l原创 2020-10-15 10:01:47 · 83 阅读 · 0 评论 -
LeetCode57插入区间
LeetCode57插入区间题目描述给出一个无重叠的 ,按照区间起始端点排序的区间列表。在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。典型的贪心问题,需要对二维数组起始端点进行排序。注意以下用法:LinkedList<int[]> output = new LinkedList<int[]>(); 可以存储二维数组return output.toArray(new int[output.size()][2]); 可以输原创 2020-10-14 21:59:54 · 95 阅读 · 0 评论 -
顺时针打印矩阵以及填写矩阵
考察我们对于规律的总结规律就是从左到右,从上到下,从右到左,从下到上,一次循环所以我们应该设置四个变量处理边界。分别是left,right,up,down,当left > right,up> down时,循环结束。class Solution { public List<Integer> spiralOrder(int[][] matrix) { List<Integer> res = new LinkedList<>();原创 2020-10-14 16:13:58 · 98 阅读 · 0 评论 -
n皇后状态压缩
class Solution { int n; int[] res; //记录每种方案的皇后放置索引 int count = 0; //总方案数 public int totalNQueens(int n) { this.n = n; this.res = new int[n]; check(0); // 第0行开始放置 return count; } //放置第k行 public voi原创 2020-10-13 17:33:30 · 131 阅读 · 0 评论 -
快速幂Java模板
递归class Solution { public double quickMul(double x, long N) { if (N == 0) { return 1.0; } double y = quickMul(x, N / 2); return N % 2 == 0 ? y * y : y * y * x; } public double myPow(double x, int n)原创 2020-10-13 11:59:41 · 129 阅读 · 0 评论 -
LeetCode48旋转图像
矩阵转置先看下数学上怎么定义转置矩阵的:将矩阵的行列互换得到的新矩阵称为转置矩阵,转置矩阵的行列式不变。同时转置矩阵有以下的运算性质:方法 1 :转置加翻转最直接的想法是先转置矩阵,然后翻转每一列。这个简单的方法已经能达到最优的时间复杂度O(N^2)。class Solution { public void rotate(int[][] matrix) { int n = matrix.length; // transpose matrix for (int原创 2020-10-13 10:28:21 · 190 阅读 · 1 评论 -
LeetCode36
LeetCode36判断数独是否有效hashset || hashmapclass Solution { private final int N = 9; public boolean isValidSudoku(char[][] board) { HashSet<Integer> [] rows = new HashSet[N]; HashSet<Integer> [] cols = new HashSet[N];原创 2020-10-08 12:01:07 · 51 阅读 · 0 评论 -
位运算的应用
LeetCode37解数独回溯利用boolean 数组进行标识。当然用hashmap也可以。class Solution { private boolean[][] line = new boolean[9][9]; private boolean[][] column = new boolean[9][9]; private boolean[][][] block = new boolean[3][3][9]; private boolean valid = fals原创 2020-10-08 11:53:54 · 128 阅读 · 0 评论 -
Hashmap使用
//因为要对每个hashmap数组进行初始化//HashMap<Integer,Integer>[] res = new HashMap[9]; //所以尖括号可以省略HashMap[] res = new HashMap[9];res[0] = new HashMap<Integer,Integer>();Hashmap用于判断数组内是否重复,所以要会找隐藏的数组比如对于数独问题,我们就可以每一行,每一列,每一个小数独都建造一个hsahmap数组。...原创 2020-10-08 08:48:20 · 368 阅读 · 0 评论 -
双指针
双指针的应用链表,数组所谓双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向或者相反方向的指针进行扫描,从而达到相应的目的。注:这里的指针,并非专指c中指针的概念,而是指索引,游标或指针,可迭代对象等这类算法包括:1.给定一个有序递增数组,在数组中找到满足条件的两个数,使得这两个数的和为某一给定的值。如果有多对数,只输出一对即可。对于这种问题,常见的算法思路不外乎遍历,回溯,但这里,双指针遍历法是一个很有效的方法。具体思路是:初始化两个指针,一个指向数组的第一转载 2020-10-06 16:34:31 · 6028 阅读 · 0 评论 -
反转链表
反转整个链表以及k个一组反转链表提醒: 做链表问题,链表不能断反转整个链表迭代class Solution { public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode curr = head; ListNode nextTemp = null; while (curr != null) { nextTemp =转载 2020-10-06 11:25:05 · 68 阅读 · 0 评论 -
利用栈实现后序遍历二叉树java
1.根节点入栈2.将根节点的左子树入栈,直到最左,没有左孩子为止3.得到栈顶元素的值,先不访问,判断栈顶元素是否存在右孩子,如果存在并且没有被访问,则将右孩子入栈,否则,就访问栈顶元素 其关键就在于需要一个前驱指针,用于判断是否该节点的右节点被访问过。public void postOrder(Node Root) { if(Root==null) { System.out.println("空树"); return; } Node tmp=Root; //当前节点原创 2020-09-29 10:28:20 · 1327 阅读 · 0 评论