算法学习之路 | 贪心思想 02

本贴最后更新于 2120 天前,其中的信息可能已经斗转星移

Question7 种花问题

/** * 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。 * 可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。 * <p> * 给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花), * 和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。 * <p> * 思路: * 先把第一个和最后一个给种上 * 然后再循环找能种上的花盆,种上之后改成1 */ public class Question7 { public boolean canPlaceFlowers(int[] flowerbed, int n) { // n=0判断 if (n == 0) { return true; } // 判断花盆数量只有一个的话 if(flowerbed.length==1){ if(flowerbed[0]==0&&n==1){ return true; } return false; } // 先排除掉第一和最后一盆 if(flowerbed[0]==0&&flowerbed[1]==0){ flowerbed[0]=1; n--; } if (flowerbed[flowerbed.length - 1] == 0 && flowerbed[flowerbed.length-2]==0) { flowerbed[flowerbed.length-1]=1; n--; } // 遍历花盆 for (int i = 1; i < flowerbed.length - 1; i++) { if (flowerbed[i] == 1) { continue; } else if (flowerbed[i - 1] == 0 && flowerbed[i + 1] == 0) { n--; flowerbed[i] = 1; } } return n <= 0 ? true : false; } }

Question 8 判断子序列

/** * 给定字符串 s 和 t ,判断 s 是否为 t 的子序列 * * 你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。 * 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。 * (例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 * * 解题思路: * 直接遍历目标数组,应用一个指针size * */ public class Question8 { public boolean isSubsequence(String s, String t) { int size = 0; for(int i = 0;i<t.length()&&size<s.length();i++){ if(s.charAt(size)==t.charAt(i)){ // 一样了,size++ size++; } } return s.length()==size?true:false; } }

Question 9 非递减数列

/** * 给定一个长度为 n 的整数数组,你的任务是判断在最多改变 1 个元素的情况下,该数组能否变成一个非递减数列。 * 我们是这样定义一个非递减数列的: 对于数组中所有的 i (1 <= i < n),满足 array[i] <= array[i + 1]。 * <p> * 解题思路: * 见注释 */ public class Question9 { public boolean checkPossibility(int[] nums) { // 非空判断 if (nums.length == 0 || nums == null || nums.length == 1) { return true; } // 定义删除次数 int index = 0; // 第一个数特殊处理 if (nums[0] > nums[1]) { index++; nums[0] = nums[1]; } for (int i = 1; i < nums.length - 1; i++) { if (nums[i] > nums[i + 1]) { // 找到非递增的数 index++; // 修改数字 最大能承受的修改的数字 // 注意这里需要进行贪心判断 if (nums[i - 1] <= nums[i + 1]) { // 此时上一个比下一个还小,那么就没必要直接改下一个了,直接修改nums[i] nums[i] = nums[i - 1]; } else { // 上一个比下一个要大,说明要实现递增就只能够修改nums[i+1]了 nums[i + 1] = nums[i]; } } } return index <= 1 ? true : false; } }

Question 10 最大子序和

/** * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 * 例如: * 输入: [-2,1,-3,4,-1,2,1,-5,4], * 输出: 6 * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 * 运用到动态规划的小知识 */ public class Question10 { public int maxSubArray(int[] nums) { // 非空判断 if (nums.length == 0 || nums == null) { return 0; } // 定义初始化最大值 int max = nums[0]; // 初始化sum int sum = 0; for (int num : nums) { if (sum > 0) { // 有所增益 sum += num; } else { // 没有增益 舍弃前者 sum = num; } // 前一个最大值已经存储好了 ,与新的最大值进行比对 max = Math.max(sum, max); } return max; } }

Question 11 划分字母区间

/** * 字符串 S 由小写字母组成。 * 我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。 * 返回一个表示每个字符串片段的长度的列表。 */ public class Question11 { public List<Integer> partitionLabels(String S) { // 非空判断 if (S == null || S.length() == 0) { return new ArrayList<Integer>(); } // 统计每个字母最后出现的位置 int[] last = new int[26]; for (int i = 0; i < S.length(); i++) { last[S.charAt(i) - 'a'] = i; } // 统计结果 List<Integer> list = new ArrayList<>(); // 记录当前最大的目标字母出现的最后位置 int maxIndex = 0; // 记录当前目标字母出现的最后位置,初始化不能为0,防止第一个字母为a int index = -1; // 记录最后i的值 int lastI = -1; // 遍历S for (int i = 0; i < S.length(); i++) { // 获取当前字母的最后出现位置 index = last[S.charAt(i) - 'a']; // 判断是否是比maxIndex还要大 if (index > maxIndex) { // 修改maxIndex 继续找 maxIndex = index; } else if (index < maxIndex) { // 直接继续,说明该字母在范围内 continue; } else if (index == maxIndex&& maxIndex==i) { // 找到一个范围了,记录 初始化数据 list.add(maxIndex-lastI); // 初始化 lastI = maxIndex; // maxIndex不能初始化为0,需要初始化为max++ 防止出现最后只剩下一个字母的情况 maxIndex++; index = -1; } } return list; } }
  • 算法
    423 引用 • 254 回帖 • 24 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...