题目
思路
使用双指针,一个指针记录买入的价格,一个记录卖出的价格;当卖出的价格比买入的低,则选择当天买入,否则就是当前的价格高于买入的价格,可以卖出;今天卖出的的情况有两种:1)今天和明天的价格种,明天的价格更低;2)没有明天了 已经是最后一天,直接选择卖出;
代码
class Solution {
public int maxProfit(int[] prices) {
// 双指针 记录最小差值
if(prices.length <= 1){
return 0;
}
int buy = 0;
int sell = 1;
int maxMoney = 0;
while(sell < prices.length){
if(prices[sell] < prices[buy]){
// 当前价格低于买入价格 则选择当前买入
buy = sell;
}
// 当前价格高于买入价格
else if((sell < prices.length -1 && prices[sell+1] < prices[sell]) || sell == prices.length - 1){
//今天卖出的情况分两种:1)今天和明天两天的价格中 明天的价格更低 那选择在今天卖出
// 2)今天是最后一天
maxMoney += prices[sell] - prices[buy];
buy = sell;
}
sell ++;
}
return maxMoney;
}
}
Tips
最开始获取明天的价格用的是sell++而不是sell+1,出来的结果就不对!要记住sell++会改变sell的值!!!!
题目
思路
第一反应,用hashmap,但是看到题目要求额外空间只能是常量级,因此选用双指针。最开始写双指针的时候,就是暴力去计算每两个数字的和是多少,提交显示超时;后面优化代码,允许大于target后,r指针往后移动,为了避免死循环,使用一个count来记录当前l指针相加的次数。虽然做出来了 但是感觉代码不够优雅!
看了题解,发现人家的双指针比我的优雅多了,r从最后一个数往前遍历!
代码
public int[] twoSum(int[] numbers, int target) {
int len = numbers.length;
int l = 0;
int r = 1;
int count = 0;
int[] re = new int[2];
while (l < r) {
int temp = numbers[l] + numbers[r];
count ++;
if (temp == target) {
re[0] = l+1;
re[1] = r+1;
return re;
}else if(temp < target){
// 当前和小于target
if(r < len-1){
// 表示r还没有走到最后一个数
r++;
}
else {
// r已经走到最后一个数了 也就是r不能取更大的值了
l++;
count = 0;
}
} else {
// 当前和大于target r往后退
if(count <=len-l-1 && r > l + 1){
// r还可以减小
r--;
}
else {
// r已经不能再退了
l++;
r = l+1;
count = 0;
}
}
}
return re;
}
// 优雅的双指针
class Solution {
public int[] twoSum(int[] numbers, int target) {
int low = 0, high = numbers.length - 1;
while (low < high) {
int sum = numbers[low] + numbers[high];
if (sum == target) {
return new int[]{low + 1, high + 1};
} else if (sum < target) {
++low;
} else {
--high;
}
}
return new int[]{-1, -1};
}
}