算法刷题
zhazhali_fenqi
这个作者很懒,什么都没留下…
展开
-
面试题 16.21. 交换和
10的5次方的复杂度,用了sort函数,达到了10的7次方的复杂度。这肯定不是最好的办法。解题思想就是交换两个数肯定不是相等的,必然一大一小,那么一定有一个数组是加一个数,一个数组是减去一个数,而这个数都是通过交换的这两个数加减所得到的,所以两个数组加上和减去的数的绝对值是相等的,那么我们需要寻找的就是两个数组的和相减,就是她们的差值,想让他们相等,只需要在数组里面寻找差值等于和的差值的一半的两个数,平均分给两个数组即可。还有就是需要注意的是即使排完序,也没有办法根据差值的大小确定谁往前走,因为一个数组原创 2022-01-04 11:36:04 · 425 阅读 · 0 评论 -
面试题 16.20. T9键盘
不是什么高效率的做法,就是写了一个映射,还是以练习java为主。class Solution { public static List<String> getValidT9Words(String num, String[] words) { HashMap<Character, Character> Sites = new HashMap<Character, Character>(); char ch='a';原创 2022-01-04 10:04:00 · 3753 阅读 · 0 评论 -
面试题 16.19. 水域大小
经典题目,用深搜即可class Solution { int[][] visited; int[] dx={1,-1,0,0,1,-1,1,-1}; int[] dy={0,0,1,-1,1,-1,-1,1}; public int[] pondSizes(int[][] land) { visited=land; List<Integer> list=new ArrayList<>(); int rows= land.l原创 2021-12-29 21:45:50 · 138 阅读 · 0 评论 -
面试题 16.17. 连续数列
class Solution { public static int maxSubArray(int[] nums) { int len=nums.length; int sum=0,ans=Integer.MIN_VALUE; for(int i=0;i<len;i++) { if(sum+nums[i]<0){ sum=0; ans=Math.max(ans,n原创 2021-12-29 19:32:49 · 211 阅读 · 0 评论 -
面试题 16.05. 阶乘尾数
就是计算有多少个5class Solution { public int trailingZeroes(int n) { int ans=0; while(n>=5){ n /= 5; ans+=n; } return ans; }}原创 2021-12-29 18:49:17 · 149 阅读 · 0 评论 -
面试题 05.06. 整数转换
class Solution { public static int convertInteger(int A, int B) { String sa=Integer.toBinaryString(A); String sb=Integer.toBinaryString(B); while (sa.length()<32) { StringBuffer stra = new StringBuffer(); s原创 2021-12-29 18:33:50 · 196 阅读 · 0 评论 -
面试题 05.01. 插入
class Solution { public static int binaryToInteger(char[] numbers) { int result = 0; for(int i=numbers.length - 1; i>=0; i--) if(numbers[i]=='1') result += Math.pow(2, (numbers.length-i - 1)); retu原创 2021-12-29 17:58:48 · 189 阅读 · 0 评论 -
面试题 05.03. 翻转数位
首先肯定是先转换成二进制字符数组。将一个0转换成1,求连续1的最大值,如果连续1中间恰好有一个0,则最大值就是两边连续1的个数加1,如果0的个数大于1,那就是连续1的个数加1,如果0的个数没有,那就是它本身。需要注意的是在转换的时候负数要是补码的形式,比如-1他的1的个数就是32个。class Solution { public static String intToBinary32(int i){ String binaryStr = Integer.toBinaryStrin原创 2021-12-29 10:05:54 · 114 阅读 · 0 评论 -
面试题 08.10. 颜色填充
一道深搜,求连通区域的最大面积,并且把连通区域里面的值置为新的newcolor。class Solution { public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { int rows= image.length;; if(rows==0||image[sr][sc]==newColor)return image; int oldColor=image[sr][sc];原创 2021-12-28 17:09:36 · 369 阅读 · 0 评论 -
面试题 16.14. **直线
判断共线,可以根据两个点列出相应的方程式,把接下来的点代入判断。也可以根据不同的两个点组成的向量是否共线判断,向量的很多知识都忘记了,大致共线的判断条件是向量a=λ向量b,(a1,a2)=λ(b1,b2) a1=λb1 a2=λb2 所以a1/b1=a2/b2=λ 可以得到a1b2==a2b1所以我们根据这个条件判断不同的两个点组成的向量是否共线 如果共线就在同一条直线上,我们就可以更新点的数目.class Solution { public int[] bestLine(int原创 2021-12-17 08:47:30 · 235 阅读 · 0 评论 -
面试题 16.11. 跳水板
我用的list,然后最后说超时了。class Solution { public int[] divingBoard(int shorter, int longer, int k) { if (k == 0) return new int[0]; ArrayList<Integer> list = new ArrayList<Integer>(); for (int i = 0; i <= k; i++) {原创 2021-12-16 18:32:01 · 790 阅读 · 0 评论 -
面试题 16.10. 生存人数
这个方法就是笨方法,写的还是复杂度高了些。public class Solution { public int maxAliveYear(int[] birth, int[] death) { int[] nums = new int[102]; int length = birth.length; for (int i = 0; i < length; i++) { for (int j = birth[i]; j &原创 2021-12-16 17:36:36 · 118 阅读 · 0 评论 -
面试题 16.09. 运算
不用乘除减实现乘法的题在之前遇到过一道,我还记得那道题的解题思路是看一个数末尾跟进行与运算,如果是0的话表明可以被2整除,我么利用位移让它除以2,让另外一个数乘以2,如果是1的话,就直接用加法加上这个数。。。。但是这个题要求不用位运算,要实现减法,直接加一个相反数就好了。关键是取反。我们可以同样的把二进制存储入数组,分别代表用poss存储1,2,4.。。一直int的最大值,用negs存储-1,-2,-4.。。一直到int的最小值,取反的实现我们是先判断传进来的数是正数还是负数,如果是整数,那么要把它变为原创 2021-12-16 17:00:07 · 168 阅读 · 0 评论 -
面试题 16.06. 最小差
本来觉得排序的话复杂度太高了,一定有O(n)的方法。我本来写了记录每次的最大最小值,然后每次遍历两个数组,用另外的一个数组的最大最小值来减去并且寻找最小的差值。但是过了40多个用例之后发现了自己理论错误的用例。所以还是用了排序的方法。class Solution { public int smallestDifference(int[] a, int[] b) { Arrays.sort(a); Arrays.sort(b); int i = 0原创 2021-12-14 22:32:11 · 216 阅读 · 0 评论 -
面试题 16.01. 交换数字
没有套路。加加减减的把它搞出来就好。class Solution { public int[] swapNumbers(int[] numbers) { if(numbers[0]==numbers[1]) return numbers; numbers[0]=numbers[0]+numbers[1]; numbers[1]=numbers[0]-numbers[1]; numbers[0]=numbers[0]-number原创 2021-12-10 10:11:13 · 190 阅读 · 0 评论 -
面试题 10.11. 峰与谷
这个题目要求的是波峰波谷波峰这样交替的顺序,所以在奇数位是波峰,偶数位是波谷。我们每次只限制当前数字的前一位,如果是波峰,要求它前面的数字比它自己要小,否则就把两个位置的数进行交换,这样当前位和他的前一位就符合题目要求了,如果是波谷,要求它前面的数字比它自己大,否则就把两个位置的数进行交换,这样我们一直处理到最后一位他的每一位就都合乎要求了。class Solution { private static int[] swap(int a, int b){ int temp = a; a =原创 2021-12-10 10:06:36 · 186 阅读 · 0 评论 -
面试题 10.10. 数字流的秩
插入排序,根据已给函数的便利,根据已给的getRankOfNumber函数,我们可以知道小于等于x的数目,那么假设返回的是index,把它当作下标,那么index这个位置之前的数都是比它小的数。那么每次track的时候,都把传进来的数插入index的位置,那么我们得到的数组是一个升序的排序数组。然后处理getRankOfNumber函数,该函数处理的是找到小于等于传进去的x的值的所有数字的数目,数组已经是升序,我们只需要找第一个小于x的数的下标,可以遍历求,我们也可以优化,用二分的方法求。class St原创 2021-12-10 09:17:08 · 198 阅读 · 0 评论 -
面试题 10.09. 排序矩阵查找
这道题我应该是写过的,套路都很熟悉,我记得是从一个横坐标的末尾,一个纵坐标的起始这样根据大小往前判断。因为可以确定的是每一行的第一个都是这一行最小的,这一行第一个之后的都比它要大一些,所以我们从最后一行开始判断,如果比当前行的当前列数字大,那么往后找,列数往后走,走到某个数字比它大,往上走。其实会发现这就是一条找到目标值的最短路径。class Solution { public boolean searchMatrix(int[][] matrix, int target) {原创 2021-12-09 17:13:49 · 110 阅读 · 0 评论 -
面试题 10.03. 搜索旋转数组
这个题上来就遍历一遍找到的话,明显配不上它中等的身份。所以一定有复杂度更低的算法。这个题目就是二分,关键是怎么寻找目标位置。如果在left位置等于目标值,我们就直接返回这个位置,之所以这样是因为题目中有重复值,我们需要找最小位置的目标值。然后如果mid这个位置的值等于目标值,我们把right等于mid,让它再往前查找是否还有合适的满足目标的值。否则的话我们就看目标值是在前部半分还是在后半部分,如果前半部分是arr[mid]大于arr[0]的,那么说明一定有小于arr[mid]并大于arr[0]的数字,下一原创 2021-12-09 16:09:40 · 100 阅读 · 0 评论 -
49. 字母异位词分组
还是先排序,看排完序后的字符串是否一致,如果一致,就把他们归为一类。刚学java,对比一下两种写法,java确实简单一些。class Solution { public List<List<String>> groupAnagrams(String[] strs) { int len=strs.length; Map<String, List<String>> res; res=new HashMap<St原创 2021-12-06 10:26:51 · 65 阅读 · 0 评论 -
面试题 10.01. 合并排序的数组
这个题目一般思路是找到一个往后位移一遍,但这种复杂度达到O(N2)。一旦复杂度达到这种程度,那一般来说都会有更加高效的做法。我的想法是先把A数组的往后位移n个位置,为下面B数组腾出空间,然后在开始比较,这样在O(N)的时间复杂度内就可以实现。class Solution { public void merge(int[] A, int m, int[] B, int n) { int i = 0, j = 0; if (n == 0) return;原创 2021-12-06 09:39:32 · 78 阅读 · 0 评论 -
面试题 08.14. 布尔运算
这个题我看了 标准答案理解了一下。我觉得有一点不同的是我们写dp是因为它可以避免递归过程中大量重复的计算,大大提高效率。而在这个题目中,我们是从最大范围一步一步往前缩小范围,看是否可以找到我们需要的方法。递归的边界条件是范围为1,看它是否符合我们想得到的结果,然后返回上一层,在上一层我们会把左右两部分的方法数相乘,并且加到最后的结果中。class Solution { private char[] arr; private int[][][] dp; private int原创 2021-12-03 11:43:37 · 151 阅读 · 0 评论 -
面试题 08.11. 硬币
一道非常经典的动态规划。class Solution { private int[] money={1,5,10,25}; public int waysToChange(int n) { int[] nums; nums=new int[n+1]; nums[0]=1; for(int i=0;i<4;i++) { for(int j=money[i];j<=n;j++) {原创 2021-12-03 09:49:00 · 445 阅读 · 0 评论 -
面试题 08.03. 魔术索引
记录我的第一次java写题,开始跟着项目学java。第一种,直接遍历。class Solution { public int findMagicIndex(int[] nums) { int len= nums.length; for(int i=0;i<len;i++) { if(nums[i]==i) return i; } return -1;原创 2021-12-02 11:03:58 · 83 阅读 · 0 评论 -
面试题 08.09. 括号
还是递归 不过有个点,就是上面的限制条件,我们先每次添加左括号,所以左括号大于n就肯定不对了,而且左括号应该是大于右括号的,然后右括号遍历直到他们相等。class Solution {public: vector<string> res; void dfs(int left, int right, string s, int n) { if (left > n || left < right) return;原创 2021-11-29 11:05:06 · 96 阅读 · 0 评论 -
有重复字符串的排列组合
加个判断就行,但明显他不是很高明的做法。class Solution {public: vector<string>res; int length; void dfs(string &S,int start) { if(start==length&&!(count(res.begin(),res.end(),S))){ res.push_back(S); return;原创 2021-11-29 10:44:22 · 119 阅读 · 0 评论 -
MySQL出错
我记得这应该是第二次了,因为对数据库是一个小白,所以每次都不小心用ctrl+z的命令退出,但是再次登录的时候就会出现这个错误提示,我能保证我的密码一定是对的,但是原因是什么我也不知道,解决办法就是每次都只能重置密码。步骤...原创 2021-11-26 22:41:27 · 778 阅读 · 1 评论 -
面试题 08.05. 递归乘法
这个题目首先就要想到位移,向右位移是除法,向左位移是乘法。首先判断末尾是否是1,如果是的话,那么它就是奇数,乘法其实就是多少个数相加,所以如果是奇数,就先加一个B,并且A减去1.如果是偶数的话那么A除以2,在B上乘以2他们的结果仍然是等价的。其实也是算A是多少个2相乘,然后把这些2乘到B上,结果是一样的。class Solution { public: int multiply(int A, int B) { int sum=0; while(A!=1)原创 2021-11-26 11:26:55 · 241 阅读 · 0 评论 -
面试题 08.04. 幂集
我的第一波回溯,写的时候就想到递归了,但是是递归的回溯,我以前写二叉树的路径等于某个值那种题目,一直在纠结为什么要减去,为什么不减去,什么时候该减去。它取决于是否回溯,要所有的子集合,就去回溯尝试所有的集合可能,也是一种暴力的方法。class Solution {public: vector<vector<int>> res; void dfs(int start,vector<int>& tmp,vector<int>&原创 2021-11-26 10:34:27 · 494 阅读 · 0 评论 -
面试题 05.08. 绘制直线
这个题目我竟然刚开始都没看懂什么意思。看了一部分题解的解释才懂这个题目什么意思。简而言之,就是把他给的这段数据分成三个部分,第一个和第三个部分就是不在(x1,y)和(x2,y)之间的部分,那第二部分自然就是在这个之间的部分了。第二部分的0是要全部置1的其他部分是0然后32位是一个整数,放进结果集合 就可以了。class Solution {public: vector<int> drawLine(int length, int w, int x1, int x2, int y) {原创 2021-11-26 09:17:56 · 371 阅读 · 0 评论 -
面试题 05.04. 下一个数
还是用的暴力法,判断每个数字1的个数是多少,因为int的最大值会溢出,所以特判了,不算特别好的方法。class Solution {public: int GetCountOne(unsigned int n) { unsigned int c = 0; for (c = 0; n; ++c) { n &= (n - 1); } return c; } vector<int>原创 2021-11-25 17:18:07 · 155 阅读 · 0 评论 -
面试题 05.02. 二进制数转字符串
这个题应该也就是个简单题,我本来以为会存在很多数据精确度的问题,没想到数据这么弱,一发就过了。知道浮点数就是小数怎么转换成二进制就都会做。class Solution {public: string printBin(double num) { string res="0."; int i=0,flag=0; double a=0.0; while(i<30) { num=num*2.0; if(num原创 2021-11-25 10:54:15 · 248 阅读 · 0 评论 -
面试题 04.12. 求和路径
跟上一道题很像,问题不大,一发过。还是遍历每一个节点,然后判断从当前节点出发有多少个满足条件的路径,最后把每一个节点相加。这道题让我想起了二叉树中等于某一值的路径那个题,当时不明白sum下面为啥不在减去,现在看来是我太菜了,当时不理解递归的本质。从某个节点出发,每条路径往下都会尝试到,根本不需要减去回溯,每一层都会保存相应的sum临时变量。class Solution {public: void pathNum(TreeNode *root, int sum, int &count原创 2021-11-25 10:26:37 · 177 阅读 · 0 评论 -
面试题 04.10. 检查子树
还是递归的思路,如何判断一棵树A是不是另外一棵树B的子树。首先要知道如果A是B的子树,那么从B的某个和A的根节点相同的节点剪下来之后,跟A应该是一模一样的树。怎么判断呢,我就是最常规的暴力解法,肯定得遍历B的每一个节点,看该节点是否和A的根节点相同,相同继续判断A的其他节点是否一样,到最后判断出是不是他的子树。我们可以把判断两棵树是否相等封装成为一个函数,然后再写一个函数遍历B的每一个节点进行判断。/** * Definition for a binary tree node. * struct T原创 2021-11-25 09:40:38 · 202 阅读 · 0 评论 -
面试题 04.08. 首个共同祖先
共同祖先,选了常用的思路,也想不出来更好的思路。就是分别保存根节点到两个节点的路径,然后比较两条路径如果是重合的部分就一直往后面走,如果不是的话就是最后要寻找的节点。需要注意的部分还是递归寻找到某个节点的路径这段代码,这个过程是在不断的尝试到达该节点的路径,所以如果在路径一颗子树里面没有找到,我们就要pop()出去,继续尝试。/** * Definition for a binary tree node. * struct TreeNode { * int val; * Tree原创 2021-11-23 10:50:55 · 410 阅读 · 0 评论 -
面试题 04.06. 后继者
这个题应该是王道考研课程讲过的,他讲了前序,中序,后续的下一个节点怎么找,其中前序和中序都是比较简单的,后序比较困难。根据中序遍历左根右我们可以推测,左根(左根右)。。。把已经知道的节点当作一个根节点,那么他的下一个节点就是当前节点的右子树的最左节点,这个根据中序遍历的顺序我们很容易可以推测出来。那么如果她没有右子树该怎么处理,这个需要总结一下规律,我们通过观察可以发现,没有右子树的节点的下一个节点,通常是当前节点在他的左子树的根节点,自己画一下,比如下面这个图4就没有右子树,他的后一个节点是5,就是4在他原创 2021-11-23 10:05:28 · 305 阅读 · 0 评论 -
判定二叉搜索树
这是我写的错误代码,在这卡了好久,错误的原因是因为我用lflag,rflag来标记是相对于根节点是左子树还是右子树,测试过后发现,根本区分不出来,到最后这两个值都会变成1,递归代码的调用顺序一定要结合并发的思想,谁先谁后,每一层的递归调用顺序。我的解体思路是除了判断他的左右节点是否符合二叉搜索树的特点以外,还得判断它相对于根节点是否符合,因为如果他的左右节点相对于当前的根节点符合,那么很有可能他的左右节点相对于最开始的根节点是不符合的,那么能走到这一步说明当前的根节点是符合的,所以只用在判断一下他跟最开始原创 2021-11-22 16:19:46 · 577 阅读 · 0 评论 -
面试题 04.03. 特定深度节点链表
这个题目就是二叉树的广度遍历加上求深度那个题目的改编。广度遍历用队列,然后遍历每一层的时候确定每一层是哪几个,把一层分离隔开。/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * };原创 2021-11-18 20:54:04 · 420 阅读 · 0 评论 -
面试题 03.03. 堆盘子
弄明白题目的含义,本质还是写栈的操作,没有什么思路,需要注意的是边界条件的判断,比如什么时候满足插入,首先vector动态数组里面不能为空要有相应数目的栈,其次vector里面的位于末尾的那个栈要没有满才可以插入,否则的话就要在vector里面开辟新的stack然后在进行插入。这个题就是用多个栈组成的数组来完成插入和删除操作。popAt的意思是要我们删除vector数组中指定的一个栈的栈顶元素。class StackOfPlates {public: vector <stack<in原创 2021-11-15 11:07:35 · 74 阅读 · 0 评论 -
面试题 01.09. 字符串轮转
en…这个题以前见过,就是拼接已经旋转过后的字符串,如果是符合要求的那个他们拼接之后一定存在s1.class Solution {public: bool isFlipedString(string s1, string s2) { if (s1 == "" && s2 == "")return true; int len1 = s1.size(); int len2 = s2.size(); if (len1 !=原创 2021-11-13 21:41:27 · 184 阅读 · 0 评论