前面的比较简单,已经写完
45. 跳跃游戏 II
很神奇,在顺好思路再写之后很快就写出来了,这个要点在于范围和最大值之间的取舍,在第一个取值的范围内找最大值,如果找到最大值了,就回到该值,然后测试该最大值是否触及边界
class Solution { public int jump(int[] nums) { int max = nums[0]; int number = 0; int max_loc = 0; if (nums.length <= 1){ return 0; } for (int i = 0;i < nums.length;i++){ int tmp_max = max; int j = i; if (max >= nums.length - 1){ number++; return number; } while (j <= tmp_max){ if (nums[j] + j > max){ max = nums[j] + j; max_loc = j; } j++; } if (max != tmp_max){ number++; i = max_loc; }else{ number++; } } return number; } }
1005. K 次取反后最大化的数组和
我的天这个题第一次自己写的特别费劲,,,不知道为什么,,意外的情况太多了 ,去看看有没有什么通用解法。。
class Solution {
int sum(int[] nums,int k){
int sum = 0;
for (int i = 0;i < nums.length;i++){
if (i <= k){
nums[i] = -nums[i];
}
sum = sum + nums[i];
}
return sum;
}
public int largestSumAfterKNegations(int[] nums, int k) {
Arrays.sort(nums);
int sum = 0;
while (k > nums.length){
if (k > 4){
k = k%4;
}else if (k == 4){
k = 2;
}
}
if (nums[k-1] <= 0){
return sum(nums,k-1);
}else{
int i = 0;
for (i = 0; i < k;i++){
if (nums[i] > 0){
break;
}
}
if (i == 0){
k = k % 2;
return sum(nums,k - 1);
}else{
i = i - 1;
if ((k - i - 1) == 0 || (k - i - 1)%2 == 0){
return sum(nums,i);
}else{
if (Math.abs(nums[i]) < nums[i+1]){
return sum(nums,i-1);
}else{
return sum(nums,i) - nums[i+1] - nums[i+1];
}
}
}
}
}
}
果然有更简单的。
class Solution {
public int largestSumAfterKNegations(int[] nums, int K) {
// 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
nums = IntStream.of(nums)
.boxed()
.sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
.mapToInt(Integer::intValue).toArray();
int len = nums.length;
for (int i = 0; i < len; i++) {
//从前向后遍历,遇到负数将其变为正数,同时K--
if (nums[i] < 0 && K > 0) {
nums[i] = -nums[i];
K--;
}
}
// 如果K还大于0,那么反复转变数值最小的元素,将K用完
if (K % 2 == 1) nums[len - 1] = -nums[len - 1];
return Arrays.stream(nums).sum();
}
}
134. 加油站
很神奇 凭直觉做出来了,,,感觉如果cost小于等于gas的话,一定是有答案的,并且找到diff最大的地方出发就好了。/。。。。
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int sum_gas = 0;
int sum_cost = 0;
int num_gas = 0;
int max_diff = 0;
for (int i = 0;i < gas.length;i++){
sum_gas = sum_gas + gas[i];
sum_cost = sum_cost + cost[i];
}
if (sum_cost > sum_gas){
return -1;
}
for (int i = 0;i < gas.length;i++){
int diff = sum_gas - sum_cost;
if (diff > max_diff){
max_diff = diff;
num_gas = i;
}
sum_cost = sum_cost - cost[i];
sum_gas = sum_gas - gas[i];
}
return num_gas;
}
}
135. 分发糖果
困难题,跳过,,,
860. 柠檬水找零
不难,想清楚条件判断就好了。
class Solution {
public boolean lemonadeChange(int[] bills) {
int count_five = 0;
int count_ten = 0;
int count_20 = 0;
for (int i = 0; i < bills.length; i++){
if (bills[i] == 5){
count_five++;
}else if (bills[i] == 10){
if (count_five == 0){
return false;
}else{
count_five--;
count_ten++;
}
}else if (bills[i] == 20){
if (count_ten >= 1){
if (count_five >= 1){
count_20++;
count_five--;
count_ten--;
}else{
return false;
}
}else if (count_five < 3){
return false;
}else if (count_five >= 3){
count_five = count_five -3;
count_20++;
}
}
}
return true;
}
}
406. 根据身高重建队列
没有什么思路,抄的别人的代码,太精妙了
class Solution {
public int[][] reconstructQueue(int[][] people) {
// 身高从大到小排(身高相同k小的站前面)
Arrays.sort(people, (a, b) -> {
if (a[0] == b[0]) return a[1] - b[1]; // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
return b[0] - a[0]; //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
});
LinkedList<int[]> que = new LinkedList<>();
for (int[] p : people) {
que.add(p[1],p); //Linkedlist.add(index, value),會將value插入到指定index裡。
}
return que.toArray(new int[people.length][]);
}
}
452. 用最少数量的箭引爆气球
这里要解决溢出的问题
不用管left也可以,因为已经排序了
class Solution {
public int findMinArrowShots(int[][] points) {
// Arrays.sort(points, (a, b) -> {
// if (a[0] == b[0]) return a[1] - b[1];
// return a[0] - b[0];
// });
//为了解决溢出问题
Arrays.sort(points, (a, b) -> {
if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
return Integer.compare(a[0], b[0]);
});
int count = 1;
int right = points[0][1];
int left = points[0][0];
for (int i = 1;i < points.length;i++){
if (points[i][1] < left || points[i][0] > right){
count++;
left = points[i][0];
right = points[i][1];
}else {
left = Math.max(left,points[i][0]);
right= Math.min(right,points[i][1]);
}
}
return count;
}
}
435. 无重叠区间
累了 休息吧。。day36
这个勉强写出来了,记得要改为最小的right,而不是最大的
763. 划分字母区间
我感觉挺难的,主要是很难想到,可以再做一遍
56. 合并区间
较为简单,基本上秒杀,但是要记住最后的类型转换以及添加最后一个数组
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> {
if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
return Integer.compare(a[0], b[0]);
});
ArrayList<int[]> result = new ArrayList<>();
int right = intervals[0][1];
int left = intervals[0][0];
for (int i = 1;i < intervals.length;i++){
if (intervals[i][0] <= right){
right = Math.max(right,intervals[i][1]);
}else{
int[] tmp = {left,right};
result.add(tmp);
left = intervals[i][0];
right = intervals[i][1];
}
}
result.add(new int[]{left, right});
return result.toArray(new int[result.size()][2]);
}
}
738. 单调递增的数字
这个题做了好久,吐了,还是不太明白
![](https://img-blog.csdnimg.cn/direct/fab05e1469cb44c1930aa40d083c3f41.png)