
LeetCode
LeetCode题解
飘来荡去、、
这个作者很懒,什么都没留下…
展开
-
岛屿的个数
思路:如果当前节点为陆地,那么就从该节点开始,按照深度优先遍历,直到遇到0就停止。遍历过程中将1赋值为0,避免重复遍历。通过这样遍历一次,就可以找到一个岛屿了。最后的矩阵中就全部为0了。相当于求连通子图代码:class Solution { public int numIslands(char[][] grid) { int count = 0; ...原创 2019-01-21 15:33:32 · 225 阅读 · 0 评论 -
寻找重复数
折半查找一、如何确定一个数是否重复?因为所有数字都在范围内,那么我们可以判断出重复数字在哪一个范围内。判断方法是:先得到的中间数,然后在中进行搜索,统计小于等于的个数,记为如果,说明重复数字在区间内如果,说明重复数字在区间内最终的重复数字就是。二、代码class Solution { public int findDuplicate(int[] num...原创 2019-01-09 13:07:50 · 506 阅读 · 0 评论 -
搜索旋转排序数组
方法还是使用折半查找。一、怎么查?因为折半查找的前提条件是数组必须有序,但是现在数组旋转了,如果可以让数组恢复顺序,那么直接折半查找就可以了。二、怎么恢复?首先想到的是:找到数组的最小值,然后根据数组长度来重新定位low和high,这样就可以满足折半查找的要求。以【4,5,6,7,0,1,2】为例,最小值的下标是4。那么,(7是数组的长度),然后计算;但是还需要判断一下是否...原创 2019-01-08 17:31:14 · 175 阅读 · 0 评论 -
在排序数组中查找元素的第一个和最后一个位置
数组有序,时间复杂度要求为,使用折半查找。一、查什么?目标值的开始位置和结束位置,普通的折半查找只能判断目标值是否在数组当中,在的话返回其下标,但是这里面的数组有重复值,所以要对折半查找进行改造。二、怎么查?先查目标值的开始位置。如何定义开始位置?如果在数组中找到目标值的位置,然后判断它左边位置上的数是否和目标值相等:如果不相等,那么此时目标值的位置就是开始位置;如果相...原创 2019-01-06 17:52:33 · 1208 阅读 · 2 评论 -
x的平方根
首先开方后的数肯定小于原数的一半,然后在之间进行折半查找,查找某一个数的平方等于x。但是因为int范围的限制,不能做乘法,用除法来判断;如果折半查找完成后任然没有找到,那么返回high位置的数即可。class Solution { public int mySqrt(int x) { if (x == 0 || x == 1){ retur...原创 2019-01-06 14:28:05 · 430 阅读 · 0 评论 -
寻找两个有序数组的中位数
方法一:合并两个数组,然后求中位数,时间复杂度为:O(m+n)class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int length1 = nums1.length; int length2 = nums2.length; ...原创 2019-01-04 13:48:09 · 550 阅读 · 0 评论 -
搜索二维矩阵
思路:题目已经说的很直接了,每一行都是升序,且每一列也是升序,所以可以使用折半查找。但是不可能对每一行都进行查找,要先定位到target可能在的那一行,然后再对这一行进行折半查找。如何定位?根据数组的最后一列,找到第一个比target值大的数所处的行,那么target极有可能就在这一行。同时如果在最后一列就找到了target值,那么直接返回即可。代码:class Solution {...原创 2019-01-03 14:34:56 · 181 阅读 · 0 评论 -
寻求峰值
寻找中间值大于左右值,且时间复杂度为O(logN),想到使用折半查找。折半查找/*折半查找*/int Binary_Search(int a*,int n,int key){ int low,high,mid; low=1; /*定义最底下标为记录首位*/ high=n; /*定义最高下标为记录末位*/ while(low<...原创 2019-01-02 13:49:52 · 272 阅读 · 0 评论 -
乘积最大子序列
最大乘积可以由正数乘正数或者负数乘负数得到,所以在扫描过程中需要记录两个数值,一个最大值(max),一个最小值(min)。如果当前元素大于等于0,那么通过比较max*nums[i]和nums[i]的大小就可以得到到i为止的最大乘积子序列。如果当前元素小于0,通过比较min*nums[i]和nums[i]的大小就可以得到到i为止的最大乘积子序列。所以可以得到状态转移方程为:当n...原创 2019-01-02 12:40:10 · 212 阅读 · 0 评论 -
整数拆分
通过证明可以得到,尽可能多的拆出3,就可以得到乘积最大。 public static int integerBreak2(int n) { if (n <= 3){ return n-1; } int result = 1; while (n > 4 ){ r...原创 2018-12-15 12:53:14 · 219 阅读 · 1 评论 -
三角形最小路径和
动态规划,最后路径和最小,那么每一步必须最小一、求解 求出到达最后一层的所有最小路径,然后再求出其中最小的即可。初始化二维数组用来存放结果final int size = triangle.get(triangle.size() - 1).size();int[][] result = new int[size][size];result[0][0] = triang...原创 2018-12-13 15:17:57 · 168 阅读 · 0 评论 -
0-1背包、完全背包、多重背包、零钱兑换
目录一、0-1背包问题1.1 问题描述1.2 动态规划过程1.3 状态转移方程1.4 填表1.5 代码1.6 回溯法求解1.7 优化二、完全背包问题2.1 问题描述2.2 分析2.3 填表2.4 代码2.5 回溯法求解2.6 优化三、多重背包3.1 问题描述3.2 分析3.3 填表3.4 代码3.5 回溯法求解...原创 2018-12-04 23:25:14 · 933 阅读 · 0 评论 -
单词拆分 II
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。说明:分隔时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。示例 1:输入:s = "catsanddog"wordDict =["cat", "cats", "and", "sand", "dog&qu原创 2018-12-03 16:25:35 · 833 阅读 · 0 评论 -
二维区域和检索 - 矩阵不可变
思路和一维的一样:首先计算result,求出每一行的所有区间和。然后累加【row1,row2】区间内每一行的和。class NumMatrix { private int[][] result; public NumMatrix(int[][] matrix) { int row = matrix.length; if(row ...原创 2018-12-01 23:10:32 · 337 阅读 · 0 评论 -
区域和检索 - 数组不可变
注意需要多次调用sumRange方法,所以不能简单的进行区间遍历求和,动态规划一下,记录一下 每个区间的和,然后根据索引直接求出结果。class NumArray { private int[] sums; public NumArray(int[] nums) { final int length = nums.length; i...原创 2018-12-01 11:23:08 · 250 阅读 · 0 评论 -
打家劫舍 II
在Ⅰ的基础上进行修改,这里面要额外考虑的就是是否偷窃第一个房间和偷窃最后一个房间,所以就分别计算一下两种情况的值,然后取最大值就可以了。偷窃第一个房间: int[] result2 = new int[length]; result2[0] = nums[0]; result2[1] = Math.max(nums[0],nums[1])...原创 2018-11-28 15:35:36 · 189 阅读 · 0 评论 -
单词拆分
动态规划。问题分解:以leetcode为例,判断一个字符串是否可以被分割成一个一个的单词,那么就就可以先判断l和eetcode是否在字典当中,只有前半部分和剩余部分都在字典当中,那么此时字符串才能被分割为单词;如果不在的话那么继续向下扫描,判断le和eetcode分别在字典当中。这里面使用一个辅助数组用来存放当前扫描位置前的判断结果,就是存放l、le等的判断结果,方便下一次判断(记忆搜...原创 2018-11-27 23:35:09 · 554 阅读 · 0 评论 -
打家劫舍
方法一:暴力法计算到达每一个房间时所能盗窃的最大金额。设当前为第i个房间,那么可以从【0,i-2】中任意一个房间直接到达第i个房间,所以需要在这里面找到最大值。class Solution { public int rob(int[] nums) { int length = nums.length; if (length == 0){ ...原创 2018-11-25 19:37:57 · 190 阅读 · 0 评论 -
删除排序数组中的重复项 II
思路:设置快慢指针k(慢),i(快)和一个计数器,判断相邻的两个数字是否相等,如果相等,则计数器加一,并且判断计数器的值是否超过2,没有超过的话k向后移动一位;如果相邻的两个数字不相等,那么将k向后移动一位,然后将num[i]中的值赋值给nums[k]。关键:k用来保证每个元素最多出现两次。不想等的时候分为两种情况:计数器的值小于2,说明nums[k]的下一个元素就是nums[i] ...原创 2018-11-25 16:05:03 · 160 阅读 · 0 评论 -
删除排序链表中的重复元素
思路:设置快慢指针,两个指针位置相差一,然后比较两个指针所指向的节点内的值,如果相同则删除q所指向的节点,然后p,q移动;如果不相同,那么直接p,q移动即可。转化:用赋值代替删除。当p和q所指向节点的值不相同时,先让p后移一位,然后将q的值赋值给p指向的节点,然后q向后移动一位。当p和q所指向节点的值相同时,q向后移动,一直找到与p不同的节点为止。最后p->next = ...原创 2018-11-25 00:12:04 · 183 阅读 · 0 评论 -
使用最小花费爬楼梯
动态规划问题,在爬楼梯的基础上增加了权值,所以这里面计算的最小路径,而不是路径的条数,整体思路还是一样。设楼梯的阶数为n,也就是cost的长度,T用来保存到达每一阶台阶的花费,那么从1~n-1阶的范围内,可以得出状态转移方程:T[i] = MIN(cost[i] + T[i - 1], cost[i] + T[i - 2])当到达第n阶的时候就需要分情况讨论了:从倒数第二个台...原创 2018-11-23 11:15:35 · 197 阅读 · 0 评论 -
报数
通过get方法来构造字符串,使用快慢指针来进行统计。class Solution { public String countAndSay(int n) { String temp = "1"; if(n == 1) return temp; for (int i = 1; i <n ; i++){ te...原创 2018-11-22 11:58:12 · 174 阅读 · 0 评论 -
最大子序和
设sum[i]为以第i个元素结尾且和最大的连续子数组。假设对于第i个元素,所有以它前面的和已经求得,那么以第i个元素结尾且和最大的连续子数组实际上可以分为两种情况:以第i-1个元素结尾且和最大的连续子数组加上第i个元素 只包含第i个元素状态转移方程为:。可以通过判断sum[i-1] + nums[i]是否大于nums[i]来做选择,而这实际上等价于判断sum[i-1]是否大于0。...原创 2019-01-02 11:08:12 · 173 阅读 · 0 评论