贪心算法或贪心思想采用贪心的策略,保证每次 *** 作都是局部最优的,从而使最后得到的结果是全局最优的。
贪心从某种意义上来讲,它不是一种算法,是一种思维,真正解决问题的是贪心思维加上其它的算法(排序、手动模拟、数据结构、搜索等),下面即将开启贪心的学习,并配合几套题目的练习。
分发饼干(简单)(排序+贪心)
把饼干和小孩的胃口值分别升序排序,用较小尺寸的饼干去满足较小胃口值的小孩。
import java.util.Arrays; class Solution { public int findContentChildren(int[] g, int[] s) { Arrays.sort(g); Arrays.sort(s); int res = 0; int i = 0, j = 0; while (i < g.length && j < s.length) { if (g[i] <= s[j]) { res++; i++; j++; }else { j++; continue; } } return res; } }分发糖果(困难)(贪心)
这道题还是没搞明白为什么,先把题解放着吧。
代码:
class Solution { public int candy(int[] ratings) { int n = ratings.length; int[] left = new int[n]; for (int i = 0; i < n; i++) { if (i > 0 && ratings[i] > ratings[i - 1]) { left[i] = left[i - 1] + 1; } else { left[i] = 1; } } int right = 0, ret = 0; for (int i = n - 1; i >= 0; i--) { if (i < n - 1 && ratings[i] > ratings[i + 1]) { right++; } else { right = 1; } ret += Math.max(left[i], right); } return ret; } }最长回文串(简单)
注意区分大小写,一看到回文题目要知道回文串里的每个字符,最多只有一个字符出现奇数次,其余都是偶数次。
class Solution { public int longestPalindrome(String s) { // 先统计已有字符串中的字符个数(区分大小写) int[] hash = new int[128]; for(int i = 0; i < s.length(); i++) { hash[s.charAt(i)]++; } // 统计最长回文长度 int ans = 0; // 注意回文串中最多有一个奇数字符(作为中间字符),其余字符都为偶数 for(int i = 0; i < 128; i++) { // 整数除 2,不论奇偶个数字符都是取偶数个,乘 2是因为左右对称,各有一半 ans += (hash[i] / 2) * 2; if (hash[i] % 2 == 1 && ans % 2 == 0) { ans++; } } return ans; } }数组拆分Ⅰ(简单)
数组从小到大排序后,累加第1 3 5 7 …位数。
class Solution { public int arrayPairSum(int[] nums) { Arrays.sort(nums); int ans = 0; int i = 0; while (i < nums.length) { ans += nums[i]; i += 2; } return ans; } }验证回文字符串Ⅱ(简单)
双指针一前一后遍历字符串,如果遇到不同的字符就试试去除前面的字符或后面的字符,去除后再判断是否为回文串。
class Solution { public boolean validPalindrome(String s) { int i = 0, j = s.length() - 1; while (i < j) { // i == j 时不用判断 if (s.charAt(i) == s.charAt(j)) { i++; j--; }else { return check(i+1, j, s) || check(i, j-1, s); } } return true; } static boolean check(int i, int j, String s) { while (i < j) { if (s.charAt(i) == s.charAt(j)) { i++; j--; }else { return false; } } return true; } }柠檬水找零(简单)
在付20美元时,需要找回15美元,优先用10美元的去找,然后再用5美元,因为5美元的可用性更高。
class Solution { public boolean lemonadeChange(int[] bills) { int[] price = new int[30]; for (int i = 0; i < bills.length; i++) { int tmp = bills[i]; if (tmp == 5) { price[tmp]++; }else if (tmp == 10) { if (price[5] > 0) { price[5]--; price[tmp]++; }else { return false; } }else { // tmp == 20,先用10块钱的去找零,5块钱更灵动 if (price[10] >= 1 && price[5] >= 1) { price[tmp]++; price[10]--; price[5]--; }else if(price[5] >= 3) { price[tmp]++; price[5] -= 3; }else { return false; } } } return true; } }
看示例就能得到规律:I从0开始放,D从N开始放,最后判别最后一个字符是什么字符再确定数组最后一个元素。
class Solution { public int[] diStringMatch(String s) { int len = s.length(); // 仔细看示例就能看出规律 int left = 0; int right = len; int[] ans = new int[len + 1]; for (int i = 0; i < len; i++) { if (s.charAt(i) == 'I') { ans[i] = left; left++; }else { ans[i] = right; right--; } } if (s.charAt(len - 1) == 'I') { ans[len] = ans[len - 1] + 1; }else { ans[len] = ans[len - 1] - 1; } return ans; } }将数组分成和相等的三个部分(简单)
整个数组的和应该能被3整除,每一部分是连续的。
class Solution { public boolean canThreePartsEqualSum(int[] arr) { // 整个数组的和必须要能被 3 整除 // 是连续的三个部分 int sum = 0; for (int i = 0; i < arr.length; i++) { sum += arr[i]; } if (sum % 3 != 0) { return false; } sum = sum / 3; int cnt = 0; int i = 0; int tmp = 0; while (i < arr.length) { tmp += arr[i]; if (tmp == sum) { cnt++; tmp = 0; } if (cnt == 3) { return true; } i++; } return false; } }玩筹码(简单)
偶数位置可以0代价放到位置0,奇数位置可以0代价放到位置1,再比较0、1筹码个数,把个数少的移到多的身上去,代价为筹码数 * 1。
class Solution { public int minCostToMoveChips(int[] position) { // 偶数位置筹码都放到 第 0 个位置 // 奇数位置筹码都放到 第 1 个位置(因为左右移2个单位,代价为 0 ) int z = 0; int f = 0; // 注意position记录一个个筹码的位置 for (int i = 0; i < position.length; i++) { if (position[i] % 2 == 0) { z++; } else { f++; } } return z > f ? f : z; } }分割平衡字符串(简单)
维护一个变量cnt,遇到R就加1,遇到L就减1,如果cnt=0说明有字符串成立了,答案+1。(重要的是贪心的思维、思路,代码实现都很简单)
class Solution { public int balancedStringSplit(String s) { int cnt = 0; int all = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == 'R') { cnt++; }else { cnt--; } if (cnt == 0) { all++; } } return all; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)