35.搜索插入位置
用二分法解决,需要注意的如果返回了末尾元素l,并且数组原来该位置的值不大于target,那么需要返回l+1;
解法1:
public int searchInsert(int[] nums, int target) {if(nums.length==0) return 0;int l=0;int r=nums.length-1;while(l<r){int mid=(l+r)>>>1;if(nums[mid]>=target){r=mid;}else{l=mid+1;}}return nums[l]>=target?l:l+1;}
解法2:可以直接返回l,并且由于是左中位数,不必担心nums[mid]越界。
public int searchInsert(int[] nums, int target) {int l=0;int r=nums.length;while(l<r){int mid=(l+r)>>>1;if(nums[mid]>target){r=mid;}else if(nums[mid]<target){l=mid+1;}else{return mid;}}return l;}
38.外观数列
用递归思想解决,后续迭代可以学习到的思想是数组的下一位不同的数字负责对上一位做出判断,注意不要忘记了最后一个和上一位不同的数字。同时计数用下标计算即可。
public String countAndSay(int n) {if(n==1) return "1";String cs=countAndSay(n-1);StringBuilder res=new StringBuilder();int start=0;int len=cs.length();for(int i=1;i<len;i++){if(cs.charAt(i)!=cs.charAt(start)){res.append(i-start).append(cs.charAt(start));start=i;}}res.append(len-start).append(cs.charAt(start));return res.toString();}
53.最大子序和
贪心法:
class Solution {public int maxSubArray(int[] nums) {if(nums.length==1) return nums[0];int cur=0;int res=Integer.MIN_VALUE;for(int i=0;i<nums.length;i++){if(cur<0) cur=nums[i];else cur+=nums[i];res=Math.max(res,cur);}return res;}}
动态规划:
public int maxSubArray(int[] nums) {int res=Integer.MIN_VALUE;int sum=0;for(int num:nums){sum=Math.max(sum+num,num);res=Math.max(sum,res);}return res;}
55.跳跃游戏
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
思路:假如每次能到达的最远距离为x,那么x之前的格子都可以尝试作为起点跳跃,并且更新它们的最远距离。
解法1:维护一个最远距离max,在max小于当前下标时返回false。
public boolean canJump(int[] nums) {int len=nums.length;if(len==1) return true;int max=nums[0];for(int i=1;i<len;i++){if(max<i) return false;max=Math.max(max,i+nums[i]);if(max==len-1) return true;}return true;}
解法2:将max作为遍历的上界,在遍历时如果max>=len-1,表示可以到达最后一个下标。否则返回false。
public boolean canJump(int[] nums) {int len=nums.length;if(len==1) return true;int max=nums[0];for(int i=1;i<=max;i++){if(max>=len-1) return true;max=Math.max(max,i+nums[i]);}return false;}
