Leetcode(easy Greedy)
阿新 • • 發佈:2020-11-04
Leetcode(easy Greedy)
leetcode 貪心演算法的簡單題目
122. 買賣股票的最佳時機 II
給定一個數組,它的第 i 個元素是一支給定股票第 i 天的價格。設計一個演算法來計算你所能獲取的最大利潤。你可以儘可能地完成更多的交易(多次買賣一支股票)。注意:你不能同時參與多筆交易(你必須在再次購買前出售掉之前的股票)。
class Solution { public int maxProfit(int[] prices) { // 貪心演算法:只要今天買明天賺就買入 // profit用來記錄前後兩天的差值 int res = 0; int[] profit = new int[prices.length - 1]; for(int i =0;i<prices.length-1;i++) profit[i] = prices[i+1] - prices[i]; for(int n:profit) if(n>0) res+=n; return res; } }
455. 分發餅乾
class Solution { public int findContentChildren(int[] grid, int[] size) { if (grid == null || size == null) return 0; Arrays.sort(grid); Arrays.sort(size); int gi = 0, si = 0; while (gi < grid.length && si < size.length) { if (grid[gi] <= size[si]) { gi++; } si++; } return gi; } }
860 檸檬水找零
class Solution { public boolean lemonadeChange(int[] bills) { if(bills == null || bills.length==0) return true; int[] money = new int[3]; for(int n:bills){ if(n==5) money[0]++; if(n==10){ if(money[0]<1){ return false; }else{ money[0]--; money[1]++; } } if(n==20){ if(money[0]>0 && money[1]>0){ money[0]-=1; money[1]-=1; money[2]++; } else if(money[0]>2){ money[0]-=3; money[2]++; } else{ return false; } } } return true; } }
874. 模擬行走機器人
class Solution {
public int robotSim(int[] commands, int[][] obstacles) {
//direction表當前朝向,0123 表 北東南西
int ans = 0,direction = 0,x = 0,y = 0;
//每個朝向上的資料變化,比如朝北時取Direction[0] -> {0,1}
//那麼x軸的變化為x+0,y軸變化為y+1;
int[][] Direction = {{0,1},{1,0},{0,-1},{-1,0}};
HashSet<String> set = new HashSet<>();
//將所有障礙物座標組合成字串存入set中方便查詢
for (int[] arr : obstacles) set.add(arr[0]+","+arr[1]);
for (int com : commands){
//定義下一步的座標
int next_x = 0,next_y = 0;
//當命令為前進,開始移動
if (com >= 0 ){
for(int i = 0; i < com; i++){
//取得下一步的座標
next_x = x + Direction[direction][0];
next_y = y + Direction[direction][1];
//若下一步有障礙物,結束當前命令,跳至下一命令
if(set.contains(next_x+","+next_y)) break;
//否則更新座標與最遠距離
x = next_x;
y = next_y;
ans = Math.max(ans, x*x + y*y);
}
}else{
//改變朝向
direction = com == -1 ? (direction + 1) % 4 : (direction + 3) % 4;
}
}
return ans;
}
}
944. 刪列造序
class Solution {
public int minDeletionSize(String[] A) {
int ans = 0;
for (int c = 0; c < A[0].length(); ++c)
for (int r = 0; r < A.length - 1; ++r)
if (A[r].charAt(c) > A[r+1].charAt(c)) {
ans++;
break;
}
return ans;
}
}
1005. K 次取反後最大化的陣列和
class Solution {
public int largestSumAfterKNegations(int[] A, int K) {
Arrays.sort(A);
int m=0;
for(int n:A) if(n<0) m++;
int flag =0;
for(int n:A) if(n==0) flag=1;
int i = 0;
while(m>0&&K>0){
A[i]=-A[i];
m--;
i++;
K--;
}
int res = 0;
if(K==0||flag==1) for(int n:A) res+=n;
else{
Arrays.sort(A);
while(K>0){
A[0]=-A[0];
K--;
}
for(int n:A) res+=n;
}
return res;
}
}
1046. 最後一塊石頭的重量
有一堆石頭,每塊石頭的重量都是正整數。
每一回合,從中選出兩塊 最重的 石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x <= y。那麼粉碎的可能結果如下:
如果 x == y,那麼兩塊石頭都會被完全粉碎;
如果 x != y,那麼重量為 x 的石頭將會完全粉碎,而重量為 y 的石頭新重量為 y-x。
最後,最多隻會剩下一塊石頭。返回此石頭的重量。如果沒有石頭剩下,就返回 0。
class Solution {
public int lastStoneWeight(int[] stones) {
// myidea : 利用一個優先佇列,每次都去敲兩塊最大的石頭,敲碎的石頭再重新進入優先佇列也就是大頂堆
Queue<Integer> queue = new PriorityQueue<>((o1, o2) -> (o2 - o1));
for(int num:stones) queue.offer(num);
while(queue.size()>1) queue.offer(Math.abs(queue.poll()-queue.poll()));
int res =0;
res = queue.poll();
return res;
}
}
1217. 玩籌碼
數軸上放置了一些籌碼,每個籌碼的位置存在陣列 chips 當中。
你可以對 任何籌碼 執行下面兩種操作之一(不限操作次數,0 次也可以):
將第 i 個籌碼向左或者右移動 2 個單位,代價為 0。
將第 i 個籌碼向左或者右移動 1 個單位,代價為 1。
最開始的時候,同一位置上也可能放著兩個或者更多的籌碼。
返回將所有籌碼移動到同一位置(任意位置)上所需要的最小代價。
class Solution {
public int minCostToMoveChips(int[] position) {
// myieda:偶數位置全部移動到偶數位置的代價是0,同理奇數位置全部移動到同一奇數位置的代價也為0,最終的結果就是奇數位置的元素和偶數位置的元素較小的那一個
int[] pos = new int[2];
for(int num:position) if(num%2==1) pos[1]++; else pos[0]++;
return Math.min(pos[0],pos[1]);
}
}
1221. 分割平衡字串
在一個「平衡字串」中,'L' 和 'R' 字元的數量是相同的。
給出一個平衡字串 s,請你將它分割成儘可能多的平衡字串。
返回可以通過分割得到的平衡字串的最大數量。
class Solution {
public int balancedStringSplit(String s) {
// myidea 貪心 記錄R與L之間的差值,若為0,res++
int res = 0;
int flag = 0;
for(char c:s.toCharArray()){
if(c=='R') flag++;
if(c=='L') flag--;
if(flag==0) res++;
}
return res;
}
}
1403. 非遞增順序的最小子序列
class Solution {
public List<Integer> minSubsequence(int[] nums) {
Arrays.sort(nums);
List<Integer> list = new ArrayList<>();
int sum = 0;
int temp = 0;
for(int i:nums) sum+=i;
for(int i=nums.length-1;i>-1;i--){
temp +=nums[i];
list.add(nums[i]);
if(temp>sum-temp) break;
}
for(int i:list) System.out.println(i);
return list;
}
}
1518. 換酒問題
class Solution {
public int numWaterBottles(int numBottles, int numExchange) {
int ans = numBottles;
while(numBottles!=0){
ans+=helper(numBottles,numExchange)[0];
numBottles=helper(numBottles,numExchange)[1]/numExchange;;
}
return ans;
}
public int[] helper(int numOfNullBottles,int numExchange){
int res = 0;
int[] temp = new int[2];
while(numOfNullBottles/numExchange!=0){
res+=numOfNullBottles/numExchange;
numOfNullBottles=numOfNullBottles%numExchange+numOfNullBottles/numExchange;
}
temp[0] = res;
temp[1] = numOfNullBottles;
return temp;
}
}