
算法
第四单元
Java程序员一枚
展开
-
【算法题解】17.电话号码的字母组合
回溯算法使用StringBuilder进行字符串的拼接,可以生成更少的String对象,执行速度更快。回溯执行的主体是取当前遍历到的数字对应的字符集合,依次加到当前已经拼接的字符串尾部,然后进行回溯。然后删除添加的当前字符,进行下一次回溯。当回溯到最后时,没有新的数字,这时将拼接好的字符串加到结果集中即可。在中间dfs的过程中巧妙利用了StringBuilder,只需要一个对象即可。使用其deleteCharAt()方法删除尾部字符,这个方法很关键,如果不知道这个方法,不太容易利用。...原创 2022-07-17 11:21:54 · 159 阅读 · 0 评论 -
【算法题解】搜索二维矩阵
给定一个m*n的矩阵,矩阵中每一行的元素从左往右依次递增,每一行的第一个元素都比上一行的最后一个元素大。给出一个目标值,编写一个高效的算法判断该目标值是否在矩阵中存在。根据题意可以分析出,没一行递增,每一列也递增。《剑指Offer》上有一道题给出的就是这样的矩阵,用那里的方法可以解决。就是从右上角或者左下角开始判断。每次可以排除一行或者一列。时间复杂度为O(m+n)。这道题里的矩阵其实比《剑指Offer》上的那道,还多了一些条件。就是这里除了行列递增外,每一行整体都比上一行大。也就是按行从左到右,一行行也原创 2022-06-04 19:29:32 · 426 阅读 · 0 评论 -
【算法题解】矩阵置零
给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。这个题目并不复杂,只需要遍历一遍数组找出为0的元素,并记录其所在的行、列。最后把这些行、列全部置为零即可。所以可以使用两个数组来分别记录行列是否存在为0的情况。时间复杂度O(m*n),空间复杂度O(m+n)。具体代码如下:但是题目要求使用原地算法,原地算法的意思是不使用额外空间。那么我们可以使用第一行、第一列进行记录,为0表示对应行或列存在为0的元素,当第一行、列本身元素就是0时也可以兼容。同时原创 2022-06-04 12:51:59 · 429 阅读 · 0 评论 -
【算法题解】颠倒二进制位
题目颠倒给定的 32 位无符号整数的二进制位。分析依次判断每一位数字是0还是1,再设置到结果的对应位置上。一个技巧是为0时不用专门设置,因为本来就是0。所以只需要设置为1的情况。另外和1<<i相与判断第i位是否为1时,需要判断是否不等于0。而不是大于0,因为也有可能是负数。public class Solution { // you need treat n as an unsigned value public int reverseBits(int n) {原创 2022-03-11 15:05:33 · 184 阅读 · 0 评论 -
【算法题解】Excel表列序号、Excel表列名称
题目Excel中的列名,和其序号有如下关系:A-1B-2……Z-26AA-27AB-28题目1:现给定一个列名求其序号题目2:给定一个序号,求其对应的列名分析题目2直接处理不容易考虑清楚,先完成题目1,再进行倒推比较容易。题目1解法。A- Z对应1-26。如果在高位则乘以26。代码如下:class Solution { public int titleToNumber(String columnTitle) { int num = 0; f原创 2022-03-10 11:25:23 · 733 阅读 · 0 评论 -
【算法题解】二叉树的最小深度
题目求二叉树的最小深度:从根节点到叶子节点的路径上分析DFS,当判断到达叶子节点时记录depth,并进行最小比较。这么做了之后发现效率较低,只击败10%的提交。思考之后发现可以进行剪枝。当当前depth大于等于min时就不需要再遍历了,因为肯定找不出更短的了。代码class Solution { public int minDepth(TreeNode root) { int[] min = {0}; dfs(root, min, 0);原创 2022-03-10 11:11:09 · 284 阅读 · 0 评论 -
一些刷题时常用但平时写的不多的Java语法总结(持续更新)
1.StringBuilder删除最后一个字符StringBuilder sb = new StringBuilder();sb.append("abc");sb.deleteCharAt(sb.length() - 1);在一些涉及字符串构造的回溯算法中,需要把上一步添加的字符给删除掉。使用deleteCharAt方法可以做到。这个方法平时用的很少,特此记录。另外获取StringBuilder可以使用length()方法。2.栈、队列的使用不管是栈还是队列,都是用LinkedList实现。与原创 2022-02-27 11:37:55 · 472 阅读 · 0 评论 -
Java简洁代码实现快排
Java实现快排排序。一种较好理解的方式。代码也比较简洁。原创 2021-03-26 20:41:56 · 382 阅读 · 0 评论 -
算法题分类整理
分类整理算法题目,方便成体系地复习。原创 2021-03-19 16:07:43 · 170 阅读 · 0 评论 -
算法面试题汇总
开始之前1.只出现一次的数字题目:一个数组中除了一个数字外都出现两次,找出这个出现一次的数字。思路:所有数字进行异或操作。相同的数字之间会相互抵消,变成0。剩下一个数字和0异或还是它本身。2.多数元素题目:在一个数组中,有一个数字出现次数大于n/2次。O(n)时间复杂度求这个数字思路:投票算法3.搜索二维矩阵II题目:一个数组。每一行的元素,从左到右递增。每一列的元素从上到下递增。给一个目标值target,求问该值是否在数组中存在。思路:从右上角开始寻找。大了往左,小了往下。或者从左下角开原创 2021-02-22 22:51:59 · 167 阅读 · 0 评论 -
【算法题解】LeetCode 58.最后一个单词的长度
题目给定一个仅包含大小写字母和空格 ’ ’ 的字符串 s,返回其最后一个单词的长度。如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词。如果不存在最后一个单词,请返回 0 。说明:一个单词是指仅由字母组成、不包含任何空格字符的 最大子字符串。题解这道题考虑怎么找到最后一个连续的不包含空字符的字符串。怎么算找到了这样的一个单词呢?其实我们只要找到字符串的开头和结尾就算找到了。既然是要在一个字符串中找,免不了要进行遍历。首先考虑从头开始遍历,我们发现不容易确定最后一个单词的开头,当遍历到一原创 2020-06-23 11:24:26 · 207 阅读 · 0 评论 -
【算法题解】LeetCode 38.外观数列
题目「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:111 (因为上一项时1,11表示1个1)21 (因为上一项为11,21表示2个1)1211(1个2,1个1所以为1211)111221(1个1 1个2 2个1,连起来为111221)给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。注意:整数序列中的每一项将表示为一个字符串。题解要求第n项,是一个遍历的过程,重复进行count and say。所以考虑提出一个方法:对原创 2020-06-23 11:09:52 · 305 阅读 · 0 评论 -
【算法题解】LeetCode 35搜索插入位置
题目给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。你可以假设数组中无重复元素。题解这一题可采用基本的二分查找算法求解。只是需要注意下“当目标值不存在于数组中”时要返回应该插入的位置,这个条件。对于这个条件,我是这么判断的。因为最后和target比较的是nums[mid],目标值插入时一定在mid前或后,所以只要再判断下和mid的大小关系就好了,再考虑下mid为边界时的情况就可以了。代码class Solution {原创 2020-06-14 17:11:53 · 179 阅读 · 0 评论 -
【算法题解】LeetCode 13.罗马数字转整数
题目罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II原创 2020-06-10 19:36:11 · 177 阅读 · 0 评论 -
【算法题解】LeetCode 9.回文数
题目判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。进阶:你能不将整数转为字符串来解决这个问题吗?解法一转换为字符串判断是否为回文字符串。class Solution { public boolean isPalindrome(int x) { if(x < 0) { return false; } String str = String.valueOf(x);原创 2020-06-10 19:34:56 · 188 阅读 · 0 评论 -
【算法题解】LeetCode 7.整数反转
题目给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。题解1反转一个数字,即从它的个位开始重新构建一个新的数字。要得到个位数字可以用last = num % 10。之后再进行num = num / 10,舍去个位数字。之后再用num % 10得到10位数字。对于新数字的生成,可以用result = result * 10 +原创 2020-06-10 19:32:39 · 208 阅读 · 0 评论 -
求斐波那契数列第n项的小技巧
class Solution { public int climbStairs(int n) { if(n <= 0) { throw new IllegalArgumentException(); } if(n <= 2) { return n; } ...原创 2020-02-29 12:10:42 · 793 阅读 · 0 评论 -
LeetCode 53题:最大子序列和
思路:动态规划的思想。设sum(i) = 以a[i]为结尾的子序列中和最大的那个子序列的和。则sum(i) = 当sum(i-1)<0是为a[i],否则为sum(i-1) + a[i]且空间复杂度度可以优化为O(1)。用sum表示sum(i-1)。当sum(i-1)<0时,将其置为0。和a[i]相加与当前记录到的最大值进行比较。...原创 2020-02-29 11:51:44 · 165 阅读 · 0 评论 -
LeetCode第11题 盛最多水的容器
思考过程:这道题和两个柱子有关,两个柱子的高度和距离决定了盛水的多少。由于和两个柱子相关,所以想到了双指针的方式。而想要盛水最多,一个方面就是让两个柱子离得尽可能远。所以双指针的起始位置是第一个位置和最后一个位置。那么怎么遍历呢?考虑了距离的远近,还有一个因素是柱子的高度。从柱子的高度看,应该尽量保留高的柱子,所以遍历的规则是较矮的柱子指针向前移动一步。正确性证明:上述解题过程并不能自证正确...原创 2020-02-27 21:40:52 · 121 阅读 · 0 评论 -
LeetCode第3题 无重复字符的最长子串
思路:滑动窗口。start和end分别表示滑动窗口的开头和结尾,表示一个没有重复字符的子串。用map记录已经访问过的字符的位置。滑动的方式是以end逐渐靠近结尾。并在过程中维护start的值。当end访问到重复字符时更新start。注意,这里start和end都只能变大,不能变小。换个角度,其实滑动窗口表示的是以end结尾的最长的最长子串。class Solution { publi...原创 2020-02-11 15:36:14 · 125 阅读 · 0 评论