题1 按摩师
描述
一个有名的按摩师会收到源源不断的预约请求,每个预约都可以选择接或不接。在每次预约服务之间要有休息时间,因此她不能接受相邻的预约。给定一个预约请求序列,替按摩师找到最优的预约集合(总预约时间最长),返回总的分钟数。
注意:本题相对原题稍作改动
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 选择 1 号预约和 3 号预约,总时长 = 1 + 3 = 4。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 选择 1 号预约、 3 号预约和 5 号预约,总时长 = 2 + 9 + 1 = 12。
示例 3:
输入: [2,1,4,5,3,1,1,3]
输出: 12
解释: 选择 1 号预约、 3 号预约、 5 号预约和 8 号预约,总时长 = 2 + 4 + 3 + 3 = 12。
题解1 递归
思路:dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
要么是当前元素加上间隔的前一个位置
class Solution {public int massage(int[] nums) {int n = nums.length;if (n == 0) {return 0;}if (n == 1) {return nums[0];}int[] dp = new int[n];dp[0] = nums[0];dp[1] = Math.max(nums[0], nums[1]);for (int i = 2; i < n; i++) {dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);}return dp[n - 1];}
}
题解2 优化
class Solution {public int massage(int[] nums) {int a = 0, b = 0;for(int i = 0; i < nums.length; i++){int c = Math.max(b, a+nums[i]);a = b;b = c;}return b;}
}
题2 打家劫舍
描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
示例 1:
输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入: [2,7,9,3,1]
输出: 12
解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
题解
与题1相同
题3 搜索插入位置
描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
题解
思路:二分查找,然后插入
执行用时 :0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗 :38.8 MB, 在所有 Java 提交中击败了71.33%的用户
class Solution {public int searchInsert(int[] nums, int target) {int start = 0, end = nums.length - 1;boolean flag = false;while(start <= end){int mid = (start+end)/2;if(nums[mid] > target){end = mid - 1;}else if(nums[mid] < target){start = mid + 1;}else{flag = true;return mid;}}int pos = nums.length;if(flag == false){for(int i = 0; i < nums.length; i++){if(target < nums[i]){pos = i;break;}}}return pos;}
}