- 博客(204)
- 收藏
- 关注
原创 C++细节积累
C++好久没用了....虽然基本的语法和代码还是没问题,但是对于一些C++的细节和具体实现并不了解。具体编码中会遇到一些错误,本文记录一下我平时约到的问题,随时更新。1. size()方法:具体是在我的for循环中判断上限是size()-3.本想想java一样当size小于3的时候上限是负数,自然跳出循环即可。但是实际工程中发现这个值是一个极大值。查阅发现,size()的返回值当i
2016-03-26 16:38:19
279
原创 leetcode: The Skyline Problem
最初想到的办法其实很暴力,遍历一遍输入,用数组记录每个x上的最高高度。但这么做在输入唯独跨度较大的时候可能不适用,而且空间消耗太大。 看了下网上的二分解法,仅记录端点也可行。由于输入是有序的(其实无序也可以),每次将输入平分为两部分,分别求得这两部分的端点后再merge即可。 二分的最终情况即仅有一个输入,此时返回这个输入矩形的左上端点和右下端点即可。merge是比较重要的。对于两个端点
2016-01-05 13:16:55
318
原创 leecode: Coin Change
一道很经典的问题,找到硬币组合成target值得最小形式....最基本的贪心法是不对的(可能会将有解的组合判定为无解),而搜索回溯的办法又会超时。不妨使用动态规划,空间代价为O(amount),数组dp[i]代表对于钱数i,当前的最小组合硬币的个数。dp[i]=min(dp[i-coins[j]]+1),j为所有小于等于i的硬币且要保证dp[i-coins[j]]有解。我们不妨令dp[i]的初
2015-12-27 12:46:53
352
原创 leetcode: Wildcard Matching
考虑正则表达式的匹配.....最初使用了一个递归的算法,但是在解决*的时候没有很好的处理(对于pattern中的每个*都遍历了所有情况),因而超时。看了下解答,其实我们只需要维护pattern中遍历到的最近的*的位置starIdx和其匹配到的str中的位置matchIdx即可,另外用sts和stp分别记录str和pattern的遍历进度。当出现无法匹配的情况,回溯到最近的*得状态,更新matc
2015-12-23 15:52:51
292
原创 leetcode: Count of Smaller Numbers After Self
输入一个数组nums,返回数组count,每一位代表nums数组中该位右侧小于该位的数的个数。 最初想到的方法就是O(n*n)的,对于每一位都统计一次右侧小于该位的数的个数(没想到可解的动态规划方法)....相比于最原始的逐位判断是否小于该位的方法,我们可以利用二分的思想来优化效率。从右至左找到每一位的count,维护一个sorted列表记录已统计的数的有序集合。当要统计nums[i]的c
2015-12-19 13:24:52
315
原创 leetcode: Course Schedule II
整体思路很容易想到,就是从没有先修课的课程入手,逐渐找到所有课程的一个可能的顺序....最初我用courseInfo来记录每门课程的先修课集合,通过while循环中每一次都扫描所有的courseInfo找出这一轮可以修的课程,但是超时;因为在比较差的条件下,这样的代价是n*n的...那么不妨用courseInfo记录每门课是哪些课程的先修课,并用一个数组preNum记录每门课的先修课数量.
2015-12-12 14:20:14
278
原创 leetcode: Repeated DNA Sequences
找出字符串中出现次数超过两次的长为10的子串。我用了最simple和粗暴的一种办法:遍历字符串所有的10长度子串,将其加入集合,当出现重复时加入结果集合。要注意结果集合的list要判重以避免出现3次以上的子串重复加入。 这里使用set来记录出现过的子串。1. 看了下其他的解法,貌似都是差不多,不知道有没有更高效的解法2. 当不限制子串长度的时候,这种解法是否可行(空间时间代价上)
2015-12-12 13:01:35
209
原创 leetcode: N-Queens
经典的N皇后问题,记录列和两条对角线的占据情况;按行遍历所有可能的皇后放置位置并回溯;将所有可能的结果记录并返回....两个注意的地方:1. 由于已找到的情况会被回溯,所以在加入结果集合中时,要用一个新的对象2. 最初我是用数组保存列和对角线的占据情况,但是超时;后来换成HashSet后即可;说明HashSet在add和remove上的效率要高与数组指定的位置的修改publ
2015-12-11 16:30:54
203
原创 leetcode: Additive Number
利用搜索的方法求解....实际上只要确定前两个数字就可以确定整个序列....那么我们不妨便利前两个数字的所有合法组合,判断这个序列是否存在....通过对两个数字搜索范围的剪枝可以加快效率,使用三个数字first, second, third代表前三个数在字符串中的起始坐标,first恒定为0;public class Solution { public boolean is
2015-12-11 14:55:02
292
原创 leetcode: Best Time to Buy and Sell Stock with Cooldown
还是采取动态规划的思路:令dp[i]代表在第I天卖出所能得到的最大收益...dp[i]有三个子状态:(1) 之前没有任何购买行为:则dp[i]=0;(2) 上一次购买不是前一天(I-1): 则dp[i]=dp[i-1]+prices[i]-prices[i-1](相当于前一天卖出的最大收益+两天的差价);(3) 上一次购买是前一天:则dp[i]=prices[i]-prices[i
2015-12-10 13:47:51
299
原创 leetcode: Remove Duplicate Letters
很有意思的一道题目,找到给定字符串的一个子序列,原字符串中的字符在这个子序列中出现且仅出现一次....而且这个子序列要保证是所有可能解中字母序最小的那个....我最初的想法就是先记录各个字符的出现次数。在O(n)的时间内按照原字符串的顺序依次将仅出现一次的字符和当前的最小字符串取出。但这样还是不能保证最小字母序,少考虑了一些情况....那么我参考了递归的解法,每次选择一个字符。这个字符是当前字
2015-12-10 12:30:08
101
原创 leetcode: Unique Paths II Super Ugly Number
ugly Number实际上就是质因子仅有给定素数构成。实际上我们不妨从1开始记录这个ugly number的列表....实际上新的ugly number是由旧的ugly number和各个素数的乘积中的最小值....我们不妨利用另一个数组记录各个素数已经考虑的情况即可public class Solution { public int nthSuperUglyNumber(i
2015-12-09 19:43:09
201
原创 leetcode: Range Sum Query 2D - Immutable
计算任意一个矩阵中矩形块的和....由于这个操作是多次的,所以这个操作尽量应该快,我们限制在O(1)的时间代价内....很容易想到利用数组sum来保存矩阵中从最左顶点到(i,j)的和....利用矩阵块的加减可以推出任意矩形区域的和...public class NumMatrix { int[][] matrixSum; public NumMatrix(int[][
2015-11-15 15:55:28
179
原创 leetcode: Basic Calculator II
模拟只有加减乘除的计算器.....我们用一个栈来尽可能的将原表达式转化为若干个加法....(因为乘除法优先,所以不能从头直接算到尾)例如,若每个数字的前一个运算符号是加号或者这个数字是第一个数的话:stack加入这个数 若这个数字之前的符号是减号的话,相当于加上这个数及其相关运算的负数,stack加入这个数的负数 若这个数字之前的符号是乘号或者除号时:由于这两种符号相比于栈中
2015-11-14 13:00:11
182
原创 leetcode: Restore IP Addresses
还是递归遍历所有可能的情况....需要注意:1. ip一共四块,每一块不能大于2552. 当当前块为0时,这一块就只能为0(因为不可能出现1.1.010.1这样的ip地址),其余的两个方向(当前块继续增加)3. 根据当前是第几块来判断“.”的添加....public class Solution { List res; public List r
2015-11-13 13:43:15
206
原创 leetcode: Word Search
DFS搜索+回溯....遍历每一个可能的路径且要mark已经走过的路径避免重复原路径,当找到符合条件的路径后返回,否则要将mark过的路径还原以便之后的搜索....public class Solution { boolean flag; public boolean exist(char[][] board, String word) { flag=f
2015-11-13 12:57:13
178
原创 leetcode: Number of Digit One
思路是从个位开始一位位的计算每一位1出现的次数....对于每一位来说由三种情况a=n/m(个位是当前计算的这位),b=n%m(这位之后的余数);那么(a%10):case > 1: count+= (a/10+1)*m;case case == 1: count+= (a/10)*m+b+1;public class Solution { public int co
2015-11-12 15:12:26
121
原创 leetcode: Course Schedule
判断给出的课程先修条件是否可能满足所有课程全部修满.....实际上我们不妨先用一个二维矩阵记录所有课程的先修关系,用一个一维数组pre记录每门课的先修课程数量....问题的突破口在于那些没有先修课程的课(否则肯定不合理,一门都修不了)。我们用一个队列queue存储可以修的课并用count记录能修的课程数,初始queue存储的是那些没有先修课的课程....遍历queue,对于其中的每一门课查找二
2015-11-12 14:25:48
171
原创 leetcode: Single Number III
按照前题的思路,还是利用异或求解....我们知道nums中的所有数异或的结果就是这两个只出现一次的数的异或结果....那么如果能找到一种分类方式将nums数组分成两组,每组中仅包含一个只出现一次的数二其他数在本组中都出现两次即可.....这种分类方法可以基于某一位的值来判断...因为出现两次的数根据某一位的值肯定都会被分在一边,而两个只出现一次的数肯定存在某一位不同.....我们不妨找到这两个数第
2015-11-12 13:42:43
162
原创 leetcode: Find Median from Data Stream
实际上使用两个队列,保证每个队列顶部恰好是中间的两个值(若large大小大于small,则说明奇数个数字,large的顶部是中间值)...保证 这个利用preority queue始终有序的特性...只需保证large的大小永远大于等于small,每次将最小的数给small;而small存数的负数形式(使得顶部最小元素即为实际的最大元素),每次将最大的值给large....这样large中始终存储
2015-11-11 13:48:52
198
原创 leetcode: Range Sum Query
由于query是频繁的,我们需要让查询的操作尽可能块,利用空间count[i]记录前i个nums的和,那么count[j]-count[i-1]便是i到j的和public class NumArray { int[] count; public NumArray(int[] nums) { count=new int[nums.length];
2015-11-11 13:23:06
216
原创 leetcode: Next Permutation
实际上要寻找下一个顺序,应该从低位开始修改....从低位开始找到首个nums[i]>nums[i-1],那么i-1位应该调整为i到len-1中大于i-1的最小数字,之后i到len-1的数字应该按照由低到高排列....当找不到这样的位的时候说明这个数字已经是最大的了,返回其最小的就可以public class Solution { public void nextPermutat
2015-11-10 14:55:56
196
原创 leetcode: Different Ways to Add Parentheses
递归的思路做这道题....原表达式中的任意一个符号可以将整个表达式分为两部分,对每一部分分别调用该方法可以得到两部分所有解得集合....我们只需遍历两个集合解的所有关于这个符号的组合加入结果列表中即可....注意:当结果列表为空的时候只可能是表达式中无加减乘符号,直接把表达式当做整数加入即可......public class Solution { public List
2015-11-10 13:41:54
230
原创 leetcode: Binary Tree Paths
从根开始遍历,分析左右子节点状态判断叶子节点以及当前节点是否应该加“->”/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x)
2015-11-09 15:57:00
195
原创 leetcode: Implement Stack using Queues
用队列来模拟栈.....可以在每次push的时候都将队列的前面所有元素重新插入一遍,这样始终保持这个队列的顺序按照栈的顺序排列即可class MyStack { // Push element x onto stack. Queue queue=new LinkedList(); public void push(int x) { que
2015-11-09 15:32:05
152
原创 leetcode: Implement Queue using Stacks
用两个栈来模拟队列,一个负责记录入栈顺序,另一个记录这个的反顺序,即队列的正常顺序...push插入input栈,O(1); pop和peek看output栈,当output为空的时候就将input内的所有数据导入过来即可....class MyQueue { // Push element x to the back of queue. Stack input=new
2015-11-09 15:03:44
152
原创 leetcode: Perfect Squares
计算n最少能由几个完全平方数组成.....最基本的想法是利用动态规划来做,dp[n]表示n最少能由几个完全平方数构成,初始dp[0]=0,其余dp[i]为MAX_VALUE.....动态规划公式为dp[j*j+i] = Math.min( dp[j*j+i],dp[i]+1 )...类似于广搜的思路,不断利用已经由完全平方数相加得到的数再去加完全平方数,,,,public class Solu
2015-09-17 12:59:42
238
原创 leetcode:First Bad Version
很简单的一道题,基本思路就是二分查找。但是需要注意的是一个细节问题....二分计算mid不要用(left+right)/2,而要使用left+(right-left)/2;只是因为面对边界条件,即right和left较大时,虽然left和right能用int表示,但是left+right有可能大于MAX_INT导致overflow,而right-left则不会存在这种情况....这也是TLE的原因
2015-09-16 10:50:55
193
原创 leetcode: H-Index
计算h值,比较容易想到的方法是将输入数组排序,从大到小与坐标比较...代价是O(nlgn)的....还可以牺牲O(n)的空间来使时间复杂度降低到O(n)...具体做法就是维护一个n+1的数组tmp记录citations中各个数出现的个数(当citations[i]>=len时,tmp[len]++)之后再从大到小遍历tmp,累加tmp[i]作为count,当第一个出现count>=坐标i的
2015-09-15 08:36:52
152
原创 leetcode: Valid Anagram
判断两个string是否由相同的字母元素组成。 首先可以从string长度上做一个初步的判断。利用一个map记录s中各个字母的出现情况,在利用这个map判断t中是否有新的字母存在来判断两个string是否相同字母构成。还有一种较为简单的办法就是用一个26的数组代替map来记录26个字母的出现情况,更加省空间public class Solution { public
2015-08-04 17:43:58
198
原创 leetcode: Combination Sum III
从1~9中找出所有可能的k个数的组合,使其和为n。采取递归的思路,传递还需要的数字个数k,数字和n,递归到哪一个数st以及当前的组合list。 通过循环(st->n/k)来作为当前可能可以插入的值继续递归下去直到k为1,判断剩余的n能否被插入,能则加入一个可能的结果到rt。 这里每一轮循环都只到n/k,保证了这一轮选的数肯定能小于后面要选的数。public class Sol
2015-08-03 13:31:58
193
原创 leetcode: Lowest Common Ancestor of a Binary Tree
寻找二叉树中任意两个节点的最近公共父节点。初始的root节点肯定是这两个节点的公共父节点。不妨从root节点开始一层层查找节点root_使得p和q分居root_两侧,那么这个root_肯定是符合条件的最近公共父节点。/** * Definition for a binary tree node. * public class TreeNode { * int val;
2015-07-29 13:36:11
113
原创 leetcode: Maximal Square
采取动态规划算法,利用一个(m+1)*(n+1)的数组来记录至各个元素位置可能存在的最大的符合条件的矩形边长。这个长度由dp[i-1][j-1],dp[i][j-1],dp[i-1][j]的最小值决定。(当且仅当这三个位置及dp[i][j]对应的matrix的点符合条件时才可++)时间代价是O(m*n)的public class Solution { public int
2015-07-28 14:53:30
174
原创 leetcode: Count Complete Tree Nodes
求近似完全二叉树的节点数。 除了最后一层外,其余各层都是满的。换句话说,最右子结点和最左子结点相差最多一个高度。 若两个节点高度一致,则可说明此时root代表的树是完全的,根据公式,其节点数为(2^height)-1;否则,其左右子树中势必有一棵是满的,我们不妨递归其左右子树,这样可以减少一半的计算量。/** * Definition for a binary tree
2015-07-27 13:37:32
191
原创 leetcode:Minimum Size Subarray Sum
找出数组中最短的子串长度,其和大于等于s。由于数组nums全是正数,那么对于任意子串sub来说,sub的所有子串的和都要小于sub。不妨用两个数字标记我们扫描的头尾,初始的st从0开始找到大于s的子串;之后不断的st++(头部逼近,缩短子串长度);当子串长度小于s时,再ed++补充子串。直到遍历完整个数组。最差相当于遍历了两边数组,时间代价是O(n)的。public
2015-07-26 13:58:49
191
原创 leetcode:House Robber II
相比于上一问,这道题加了一个限制条件是房子是一个环,即nums[0]和nums[n-1]是相邻的,两个房间不能同时抢劫。 那么实际上这个环可以分解为0到length-2以及1到length-1这两个区间,区间内的求解和上一问一致,求最大值即可。(即选不选择nums[0]的两种可能性比较一下,其他的思想和上一问一致)public class Solution { public
2015-07-25 10:36:42
176
原创 leetcode: Search a 2D Matrix II
利用这个矩阵的特性,从matrix[0][m-1]开始扫描,若小于target则到下一行,若大于target则左移。public class Solution { public boolean searchMatrix(int[][] matrix, int target) { int n = matrix.length; int m = mat
2015-07-24 13:08:09
186
原创 leetcode: Majority Element II
寻找数组中出现次数超过1/3的众数。实际上数组中符合条件的众数最多只可能存在两个。我们不妨用n1和n2来表示,count1和count2来表示这两个数出现的次数。遍历数组,当ni重复出现,增加counti,否则减少count1和count2。若counti为0,则可以换一个新的数作为新的ni。这样做肯定能够保证最终符合条件的众数在n1和n2中(i的每一次出现,要么导致其count++,要么导致
2015-07-23 09:55:31
208
原创 leetcode: Kth Smallest Element in a BST
寻找BST中第k小的节点。看了下,主流有两种解法。1. 利用BST的特性:若节点n有i个左子结点,则其一定是第i+1小的节点。我们不妨加一个方法countNum(Node)来计算Node和其所有子节点的数量从而确定Node父节点的大小,通过比较判断第k个节点在左侧还是右侧,不断逼近。/** * Definition for a binary tree node. * public
2015-07-22 11:49:09
178
原创 leetcode: Product of Array Except Self
最开始的想法是不妨求出所有数的乘积,再依次除得到各位的输出结果。但是由于nums中各位都有可能是0,而且所有数的乘积也有可能大于int_max,所以这么做要考虑的地方很多,不太可行。我们不妨先求出前i-1个数的乘积,再从后之前乘以后面的连续乘积即可。public class Solution { public int[] productExceptSelf(int[
2015-07-21 12:35:27
235
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人