/Algorithms

LeetCode solutions

Primary LanguageJava

小盒子 LeetCode 215/1615

Algorithms

1 Binary Search

1.1 Reduce Interval

  • LeetCode 35 - 搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 你可以假设数组中无重复元素。

  • LeetCode 69 - x的平方根

    实现 int sqrt(int x) 函数。

  • LeetCode 367 - 有效的完全平方数

    给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。

  • LeetCode 658 - x的平方根

    给定一个排序好的数组,两个整数 k 和 x,从数组中找到最靠近 x(两数之差最小)的 k 个数。 返回的结果必须要是按升序排好的。如果有两个数与 x 的差值一样,优先选择数值较小的那个数。

  • LeetCode 704 - 二分查找

    给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

  • LeetCode 852 - 山脉数组的峰顶索引

    给定一个确定为山脉的数组,返回唯一一个满足 A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1] 的 i 的值。

1.2 Find Left Boundary

1.3 Find Right Boundary

1.4 Rotated Sorted Array

2 Dynamic Programming

2.1 1D-DP

2.2 2D-DP

2.3 KMP

  • LeetCode 28 - 实现 strStr()

    给定一个 haystack 字符串和一个 needle 字符串, 在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。 如果不存在,则返回  -1。

  • LeetCode 572 - 另一个树的子树

    给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。 s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

2.4 Knapsack Problem

  • LeetCode 377 - 组合总和IV

    给定一个由正整数组成且不存在重复数字的数组,找出和为给定目标正整数的组合的个数。

    思路:经典0-1背包问题,但顺序不同的序列被认为不同的组合。

  • LeetCode 518 - 零钱兑换II

    给定不同面额的硬币和一个总金额。写出函数来计算可以凑成总金额的硬币组合数。假设每一种面额的硬币有无限个。

    思路:经典0-1背包问题。重点:把二维数组优化成一维数组。

  • LeetCode 面试题08.11 - 硬币

    给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。

    思路:DP[{c1, c2,... ck}][n] = DP[{c1, c2,... ck}][n - ck.value] + DP[{c1, c2,... ck-1}][n];

  • LeetCode 983 - 最低票价

    在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。 在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。

2.5 Catalan Number

  • LeetCode 96 - 不同的二叉搜索树

    给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种?

    思路:G[n] = G[0] * G[n - 1] + G[1] * G[n - 2] + ... + G[n - 1] * G[0]

3 Divide & Conquer

4 Bit Operation

4.1 Bit-XOR/OR/AND

  • LeetCode 136 - 只出现一次的数字

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

    思路:两个相等的数异或为0。异或所有数字即可得到唯一只出现一次的数字。

  • LeetCode 137 - 只出现一次的数字II

    给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。

    思路:3个元素的每位的和必定是3的倍数。

  • LeetCode 231 - 2的幂

    给定一个整数,编写一个函数来判断它是否是 2 的幂次方。

    思路:2的幂次方数最高位二进制最高位为1,其余皆为0。2的幂次方数-1的最高位为0,其余皆为1。

  • LeetCode 260 - 只出现一次的数字III

    给定一个整数数组,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。

    思路:异或所以数字即可得到两个元素只出现一次的元素的异或结果。 找到异或结果的为1的位,即两个数在这个位上不同。 遍历每个数字,将这个位上为1的分成一组,为0的分成另外一组,则两个只出现一次的元素必定在两个组里。 对两个组异或的结果就是要找的元素。

4.3 Binary-ADD/MUL/DIV

  • LeetCode 50 - Pow(x, n)

    实现 pow(x, n) ,即计算 x 的 n 次幂函数。

    思路:快速幂,即幂可以由二进制的形式表示。

4.4 Decimal-ADD/MUL/DIV

  • LeetCode 2 - 两数相加

    给出两个非空的链表用来表示两个非负的整数。其中,它们各自的位数是按照逆序的方式存储的,并且它们的每个节点只能存储一位数字。

    思路:十进制位运算。

  • LeetCode 7 - 整数反转

    给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

    思路:十进制位运算。每次循环要判断累加值乘10以后是否过界,以及乘10以后加余数是否过界。

  • LeetCode 8 - 字符串转换整数

    你来实现一个 atoi 函数,使其能将字符串转换成整数。

    思路:十进制位运算。要判断正负号,以及每次循环要判断累加值乘10以后是否过界,以及乘10以后加余数是否过界。

  • LeetCode 9 - 回文数

    判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

    思路:十进制位运算,只需要判断数的一半是否相等。

  • LeetCode 43 - 字符串相乘

    给定两个以字符串形式表示的非负整数num1和num2,返回num1和num2的乘积,它们的乘积也表示为字符串形式。

    思路:十进制乘法位运算,m位数整数*n位数整数的最大位数为m+n

  • LeetCode 29 - 两数相除

    给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

5 DFS/BFS

5.1 DFS

  • LeetCode 79 - 单词搜索

    给定一个二维网格和一个单词,找出该单词是否存在于网格中。

    思路:DFS+回溯,回溯时状态重置。

  • LeetCode 130 - 被围绕的区域

    给定一个二维的矩阵,包含 'X' 和 'O'(字母 O)。 找到所有被 'X' 围绕的区域,并将这些区域里所有的 'O' 用 'X' 填充。

  • LeetCode 200 - 岛屿数量

    给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

    思路:纯DFS,也可以用纯BFS

  • LeetCode 695 - 岛屿的最大面积

    找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0。)

    思路:纯DFS

  • LeetCode 207 - 课程表

    你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1] 给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?

    思路:判断有向图是否有环。DFS如果有back edge即为有环

  • LeetCode 210 - 课程表II

    给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。

5.2 BackTracking

  • LeetCode 22 - 括号生成

    数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。

5.2.1 Combination
  • LeetCode 77 - 组合

    给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。

  • LeetCode 39 - 组合总和

    给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的数字可以无限制重复被选取。

  • LeetCode 40 - 组合总和II

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用一次。

  • LeetCode 216 - 组合总和III

    找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

  • LeetCode 78 - 子集

    给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    思路:子集就是每个元素选择或者不选择的全排列,使用回溯算法。同层的使用交换来实现状态回溯。

  • LeetCode 90 - 子集II

    给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

    思路:对于任意一个整数,第一次遍历到这个整数时可以选择添加或者不添加。 当不是第一次遍历到这个整数时,如果子集里没有这个整数,还是可以选择添加或者不添加。 但是如果子集里已经有这个整数了,那就必须添加这个整数,不然会造成重复。

5.2.2 Permutation
  • LeetCode 17 - 电话号码的数字组合

    给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

    思路:全排列使用回溯算法。同层的使用交换来实现状态回溯。

  • LeetCode 46 - 全排列

    给定一个没有重复数字的序列,返回所有不重复的全排列。

    思路:全排列使用回溯算法。同层的使用交换来实现状态回溯。

  • LeetCode 47 - 全排列II

    给定一个可包含重复数字的序列,返回其所有可能的全排列。

    思路:全排列使用回溯算法。同层的使用交换来实现状态回溯。判断是否和同层的节点值相同从而剪枝

  • LeetCode 面试题08.08 - 有重复字符串的排列组合

    有重复字符串的排列组合。编写一种方法,计算某字符串的所有排列组合。

    思路:回溯+剪枝

5.3 BFS

  • LeetCode 542 - 01矩阵

    给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。

    思路:多源BFS

5.3.1 Dijkstra
  • LeetCode 743 - 网络延迟时间

    给定一个列表 times,表示信号经过有向边的传递时间。  times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节点传递到目标节点的时间。 现在,我们从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1。

    思路:Dijkstra

Data Structures

1 Binary Tree

1.1 Iterative Method

  • LeetCode 114 - 二叉树展开为链表

    给定一个二叉树,原地将它展开为链表。

    思路:使用迭代版前序遍历,用一个临时节点保存上一个弹出的节点。

  • LeetCode 144 - 二叉树的前序遍历

    给定一个二叉树,返回它的前序遍历。

    思路:用栈模拟系统。后进先出,所以先右后左。

  • LeetCode 94 - 二叉树的中序遍历

    给定一个二叉树,返回它的中序遍历。

    思路:用栈模拟系统。尽可能的压左边的节点进栈,没左边节点可压时,就可以打印栈顶节点并向右节点进发了。

  • LeetCode 145 - 二叉树的后序遍历

    给定一个二叉树,返回它的后序遍历。

    思路:用栈模拟系统。尽量压左节点,无左节点时如果也无右节点弹出。如果有右节点但右节点已经遍历过也可弹出。如果右节点没有遍历过向右节点迭代。

1.2 Recursive Method

1.3 BFS

  • LeetCode 102 - 二叉树的层次遍历

    给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。

  • LeetCode 103 - 二叉树的锯齿形遍历

    给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

    思路:对于从右往左的遍历,可以使用递归完成。

  • LeetCode 107 - 二叉树的层次遍历II

    给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

  • LeetCode 199 - 二叉树的右视图

    给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

1.4 DFS

2 Array

  • LeetCode 6 - Z字形变换

    将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

  • LeetCode 38 - 外观数列

    「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

  • LeetCode 169 - 多数元素

    给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

    思路:摩尔投票法

  • LeetCode 31 - 下一个排列

    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

    思路:数学分析

3 Hash Table

4 Linked List

4.1 Recursive Method

  • LeetCode 24 - 两两交换链表中的节点

    给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

    思路:递归的交换两个节点以后的节点,返回当前两个节点的后一个节点。

  • LeetCode 445 - 两数相加II

    给你两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。 它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。你不能对列表中的节点进行翻转。

    思路:计算链表长度差,使尾部对齐,递归的生成新节点(为两个链表的节点和)。

4.2 Double Pointers

5 Disjointed Set Union

  • LeetCode 547 - 朋友圈

    班上有 N 名学生。其中有些人是朋友,有些则不是。他们的友谊具有是传递性。 如果已知 A 是 B 的朋友,B 是 C 的朋友,那么我们可以认为 A 也是 C 的朋友。所谓的朋友圈,是指所有朋友的集合。 给定一个 N * N 的矩阵 M,表示班级中学生之间的朋友关系。 如果M[i][j] = 1,表示已知第 i 个和 j 个学生互为朋友关系,否则为不知道。 你必须输出所有学生中的已知的朋友圈总数。

    思路:并查集

  • LeetCode 684 - 冗余连接

    在本问题中, 树指的是一个连通且无环的无向图。 输入一个图,该图由一个有着N个节点 (节点值不重复1, 2, ..., N) 的树及一条附加的边构成。 附加的边的两个顶点包含在1到N中间,这条附加的边不属于树中已存在的边。 结果图是一个以边组成的二维数组。每一个边的元素是一对[u, v] ,满足 u < v,表示连接顶点u 和v的无向图的边。 返回一条可以删去的边,使得结果图是一个有着N个节点的树。如果有多个答案,则返回二维数组中最后出现的边。 答案边 [u, v] 应满足相同的格式 u < v。

    思路:并查集

  • LeetCode 721 - 账户合并

    思路:哈希表映射+并查集

6 Stack

7 Dictionary Tree

8 Matrix

Solutions that I failed to understand

29, 560