这个题实现并不难,关键是要从后往前扫,才能保证从后往前存入的时候不会把没有扫到的值覆盖掉。
Subsets 这道题本来没啥好说的,recursion想法和 Combination 题目近似,但是在做的时候偶然发现一个问题:在IntelJ里面追踪res的时候,尽管最后结果对,但过程中res变化不正常,
以nums = [1,2]为例, 如果每次加入res时候不传temp对copy而是传本身,在每次迭代中输出res,结果如下:
[[]]
[[1], [1]]
[[1], [1, 2], [1, 2]]
[[2], [1], [1, 2], [2]]
[[], [1], [1, 2], [2]]
可以看出,最后是对的,但过程但记录是不合理但。如何换位传入 remp对copy,整个过程就合理了
[[]]
[[], [1]]
[[], [1], [1, 2]]
[[], [1], [1, 2], [2]]
最后发现是temp在加入res时候没有copy,尽管在同一层最好的变化是被抵消了吧,但是还是不规范,一定要注意recursion中传参问题。另外附加一种iteration的经典思路,code来自Coder_Ganker大神
public class Solution {
public List
> subsets(int[] nums){
List
> res = new ArrayList
>(); List
temp = new ArrayList
(); if(nums == null || nums.length == 0) return res; Arrays.sort(nums); helper(nums,0,res,temp); return res; } public void helper(int[] nums, int s, List
> res, List
temp ){ res.add(new ArrayList
(temp)); if(s>nums.length-1) return; for(int i=s;i
(temp)); temp.remove(temp.size()-1); } } } //Iteration public ArrayList
> subsets(int[] S) { ArrayList
> res = new ArrayList
>(); res.add(new ArrayList
()); if(S == null || S.length == 0) return res; Arrays.sort(S); for(int i=0;i
item = new ArrayList
(res.get(j)); item.add(S[i]); res.add(item); } } return res; }
public class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
if(obstacleGrid == null || obstacleGrid.length==0 || obstacleGrid[0].length==0)
return 0;
int[] res = new int[obstacleGrid[0].length];
res[0] = 1;
for(int i=0; i
0)
res[j] += res[j-1];
}
}
return res[obstacleGrid[0].length-1];
}
}
Binary search has always been my weakness. However, consider I just seriously start doing algorithm coding problems, bear with it for now. I should take a big lesson from this one. What is A binary search do? --- it always go to left OR right part in next iteration until two sides finally merge. Where does binary search end? --- In last iteration, when l == r, you can either change r or change l, which is both correct or harmless. The question is, I should know clearly which one is finally changing and which one remains in right ending position. In this problem, we do 2 BSs to find right position and left respectively. We want to use ll as l and rr as r, so we modify lr and rl at end of two BSs.
public class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = new int[2];
if(nums == null || nums.length == 0)
return res;
int ll = 0;
int lr = nums.length - 1;
while(ll <= lr){
int mid = (ll+lr)/2;
if(nums[mid] >= target){
lr = mid - 1;
}else{
ll = mid + 1;
}
}
int rl = 0;
int rr = nums.length - 1;
while(rl <= rr){
int mid = (rl+rr)/2;
if(nums[mid] > target){
rr = mid - 1;
}else{
rl = mid + 1;
}
}
if(ll <= rr)
res = new int[]{ll,rr};
else
res = new int[]{-1,-1};
return res;
}
}
Jump Game : *
Jump Game II : **
Follow up is returning minimum steps needed to reach the last index. The code is also O(n) solution.
Coder_Ganker .... 大神就是大神 。。。记住for循环这种用法
另外还加了一种实现,同样的思路,用的是for + while, 注意for 的用法, 实质是 while + while
public class Solution {
public boolean canJump(int[] nums) {
if(nums == null || nums.length == 0)
return false;
int reach = 0;
for(int i = 0; i<=reach && i< nums.length; i++){
reach = Math.max(nums[i]+i,reach);
}
if(reach >= nums.length - 1)
return true;
return false;
}
}
public class Solution {
public int jump(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
int reach = 0;
int last_reach = 0;
int step = 0;
for(int i=0; i<=reach && i
last_reach){
last_reach = reach;
step += 1;
}
reach = Math.max(nums[i]+i, reach);
}
if(reach >= nums.length-1){
return step;
}else{
return 0;
}
}
}
//Another implement, same idea.
public class Solution {
public int jump(int[] nums) {
int reach=0,last_reach=0,num=0;
int n = nums.length;
for(int i=0;i
=n-1)break;
while(i<=last_reach)
{
reach=Math.max(reach,i+nums[i]);
++i;
}
num++;
last_reach=reach;
if(last_reach < i){
return 0;
}
}
return num;
}
}
public class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int diff = target - nums[0]- nums[1] - nums[2];
if(nums.length == 3){
return target - diff;
}
for(int i=0; i< nums.length-2;i++){
int t2 = target - nums[i];
int d2 = helper(nums,t2,i+1,nums.length-1);
diff = Math.abs(diff) > Math.abs(target - nums[i] - (t2 - d2) )? target - nums[i] - (t2 - d2):diff;
}
return target - diff;
}
public int helper(int[] nums, int target, int s, int e){
int diff = target - nums[s] - nums[s+1];
if(s+1 == e)
return diff;
while(s < e){
diff = Math.abs(diff) > Math.abs(target - nums[s] - nums[e] )? target - nums[s] - nums[e] : diff;
if(nums[s] + nums[e] == target){
diff = 0;
break;
}else if(nums[s] + nums[e] > target){
e -- ;
}else{
s++;
}
}
return diff;
}
}