LeetCode:1005. K 次取反后最大化的数组和 - 力扣(LeetCode)
1.思路
对数组进行升序排序,当数组元素小于0且k大于0时,取绝对值进行加和,当k==0时,直接加上数组元素值即可。当遍历结束且k还大于0,取模==0,直接忽略,取模==1时就选择一个绝对值最小的元素进行减操作。
2.代码实现
class Solution {
public int largestSumAfterKNegations(int[] nums, int k) {
// 找到数值小于 0 的,优先绝对值大的加符号,排序
Arrays.sort(nums);
// 记录绝对值的最小值 value
int value = Integer.MAX_VALUE;
// 求和 sum
int sum = 0;
for (int i = 0; i < nums.length; i++) {
value = Math.min(Math.abs(nums[i]), value);
if (nums[i] < 0) {
if (k > 0) {
sum += Math.abs(nums[i]);
k--;
} else {
sum += nums[i];
}
} else if (nums[i] >= 0) {
sum += nums[i];
}
}
if (k > 0 && k % 2 == 1) {
sum -= 2 * value;
}
return sum;
}
}
3.复杂度分析
时间复杂度:O(logn).
空间复杂度:O(1).
LeetCode:134. 加油站 - 力扣(LeetCode)
1.思路
双层for循环超时。采用贪心的思路,设置当前剩余油量和当前剩余总油量,如果当前剩余油量小于0,则标记从下一个索引位置进行加和,同时当前油量置为0。遍历结束之后,如果当前总剩余油量小于0,表示从任何一个位置都不能形成循环,反之,上面标记的下一个索引就是能走到循环末尾的索引。
2.代码实现
// 超时算法
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
// 油剩余量 消耗量cost
int restGas = 0;
for (int i = 0; i < gas.length; i++) {
// 剩余油量
restGas += gas[i] - cost[i];
int count = 0;
int j = i;
while (restGas >= 0) {
j++;
restGas += gas[j % gas.length] - cost[j % gas.length];
count++;
if (count == gas.length) {
return i;
}
}
restGas = 0;
}
return -1;
}
}
// 不太好想的思路
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
// 当前油量
int currentSum = 0;
// 总油量
int totalSum = 0;
// 满足要求的索引下标index
int index = 0;
for (int i = 0; i < gas.length; i++) {
currentSum += gas[i] - cost[i];
totalSum += gas[i] - cost[i];
if (currentSum < 0) { // 说明当前油量剩余量不足
index = (i + 1) % gas.length; // 需要从下一个索引位置进行衡量
currentSum = 0; // 可能存在连续不足的情况,故重置为0,循环执行
}
}
if (totalSum < 0) {
return -1;
}
return index;
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(1).
LeetCode:135. 分发糖果 - 力扣(LeetCode)
1.思路
创建糖果数组,存放每个小孩得到的最少糖果数,根据规则分别从左右两侧进行遍历。
2.代码实现
class Solution {
public int candy(int[] ratings) {
if (ratings.length == 1) {
return 1;
}
int[] candyCount = new int[ratings.length];
candyCount[0] = 1;
// 右边大于左边
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1]) {
candyCount[i] = candyCount[i - 1] + 1;
} else {
candyCount[i] = 1; // 当右边小于左边时给个默认值1
}
}
// 左边大于右边
for (int i = ratings.length - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) {
candyCount[i] = Math.max(candyCount[i], candyCount[i + 1] + 1);
}
}
int sum = 0;
for (int i = 0; i < candyCount.length; i++) {
sum += candyCount[i];
}
return sum;
}
}
3.复杂度分析
时间复杂度:O(n).
空间复杂度:O(n).