分发饼干
Leetcode - 455 Assign Cookies (Easy)
题目描述:每个孩子都有一个满足度,每个饼干都有一个大小,只有饼干的大小大于等于一个孩子的满足度,该孩子才会获得满足。求解最多可以获得满足的孩子数量。
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int gi = 0, si = 0;
while (gi < g.length && si < s.length) {
if (s[si] >= g[gi]) {
gi++;
}
si++;
}
return gi;
}
无重叠区间
Leetcode - 435 Non-overlapping Intervals (Medium)
题目描述:给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
解释思路:根据右边界进行排序,选择的区间结尾越小,留给后面的区间空间越大,依次判断当前左区间是否大于等于上一个的右区间。
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) return 0;
Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[1], i2[1]));
int end = Integer.MIN_VALUE, count = 0;
for (int i = 0; i < intervals.length; i++) {
if (intervals[i][0] >= end) end = intervals[i][1];
else count++;
}
return count;
}
用最少数量的箭引爆气球
Leetcode - 452 Minimum Number of Arrows to Burst Balloons (Medium)
题目描述:气球在一个水平数轴上摆放,可以重叠,飞镖垂直投向坐标轴,使得路径上的气球都被刺破。求解最小的投飞镖次数使所有气球都被刺破。
解题思路:计算不重叠的区间个数。
public int findMinArrowShots(int[][] points) {
if (points.length == 0) {
return 0;
}
Arrays.sort(points, Comparator.comparingInt(o -> o[1]));
int cnt = 1, end = points[0][1];
for (int i = 1; i < points.length; i++) {
if (points[i][0] <= end) {
continue;
}
cnt++;
end = points[i][1];
}
return cnt;
}
根据身高重建队列
Leetcode - 406 Queue Reconstruction by Height (Medium)
题目描述:假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。
Input:
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
Output:
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
public int[][] reconstructQueue(int[][] people) {
if (people == null || people.length == 0 || people[0].length == 0) {
return new int[0][0];
}
Arrays.sort(people, (a, b) -> (a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]));
List<int[]> queue = new ArrayList<>();
for (int[] p : people) {
queue.add(p[1], p);
}
return queue.toArray(new int[queue.size()][]);
}
买股票的最佳时机
Leetcode - 121 Best Time to Buy and Sell Stock (Easy)
题目描述:如果你最多只允许完成一笔交易,计算能获取的最大利润。
public int maxProfit(int[] prices) {
int minPrice = Integer.MAX_VALUE;
int maxProfit = 0;
for (int i = 0; i < prices.length; i++) {
if (i != 0) {
maxProfit = Math.max(maxProfit, prices[i] - minPrice);
}
minPrice = Math.min(minPrice, prices[i]);
}
return maxProfit;
}
买股票的最佳时机 II
Leetcode - 122 Best Time to Buy and Sell Stock II (Easy)
题目描述:能够进行多次交易,计算能获取的最大利润。
public int maxProfit(int[] prices) {
int max = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
max += prices[i] - prices[i - 1];
}
}
return max;
}
种花问题
Leetcode - 605 Can Place Flowers (Easy)
题目描述:有一个花坛,不能连续种花,1 表示种了花, 0 表示没种花,给定 n 朵花,判断是否能种入花坛。
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int cnt = 0;
for (int i = 0; i < flowerbed.length && cnt < n; i++) {
if (flowerbed[i] == 1) continue;
int pre = i == 0 ? 0 : flowerbed[i - 1];
int next = i == flowerbed.length - 1 ? 0 : flowerbed[i + 1];
if (pre == 0 && next == 0) {
cnt++;
flowerbed[i] = 1;
}
}
return cnt >= n;
}
判断子序列
Leetcode - 392 Is Subsequence (Medium)
题目描述:给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
public boolean isSubsequence(String s, String t) {
int index = -1;
for (char c : s.toCharArray()) {
index = t.indexOf(c, index + 1);
if (index == -1)
return false;
}
return true;
}
非递减序列
Leetcode - 665 Non-decreasing Array (Easy)
题目描述:在最多改变一个元素的情况下,判断该数组能否变成一个非递减序列。
解题思路:在出现 nums[i] < nums[i - 1] 时,需要考虑的是应该修改数组的哪个数,使得本次修改能使 i 之前的数组成为非递减数组,并且 不影响后续的操作 。优先考虑令 nums[i - 1] = nums[i],因为如果修改 nums[i] = nums[i - 1] 的话,那么 nums[i] 这个数会变大,就有可能比 nums[i + 1] 大,从而影响了后续操作。还有一个比较特别的情况就是 nums[i] < nums[i - 2],修改 nums[i - 1] = nums[i] 不能使数组成为非递减数组,只能修改 nums[i] = nums[i - 1]。
public boolean checkPossibility(int[] nums) {
int cnt = 0;
for (int i = 1; i < nums.length && cnt < 2; i++) {
if (nums[i] >= nums[i - 1]) {
continue;
}
cnt++;
if (i - 2 >= 0 && nums[i - 2] > nums[i]) {
nums[i] = nums[i - 1];
} else {
nums[i - 1] = nums[i];
}
}
return cnt <= 1;
}
最大子序和
Leetcode - 53 Maximum Subarray (Easy)
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
public int maxSubArray(int[] nums) {
if (nums == null || nums.length == 0)
return 0;
int preSum = nums[0];
int max = preSum;
for (int i = 1; i < nums.length; i++) {
preSum = preSum > 0 ? preSum + nums[i] : nums[i];
max = Math.max(max, preSum);
}
return max;
}
划分字母区间
Leetcode - 763 Partition Labels (Medium)
题目描述:划分字母区间,使得同一个字母只会出现在其中一个片段。
Input: S = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
public List<Integer> partitionLabels(String S) {
int[] lastIndexOfChar = new int[26];
for (int i = 0; i < S.length(); i++) {
lastIndexOfChar[S.charAt(i) - 'a'] = i;
}
List<Integer> res = new ArrayList<>();
int firstIndex = 0;
while (firstIndex < S.length()) {
int lastIndex = firstIndex;
for (int i = firstIndex; i < S.length() && i <= lastIndex; i++) {
int index = lastIndexOfChar[S.charAt(i) - 'a'];
if (index > lastIndex) {
lastIndex = index;
}
}
res.add(lastIndex - firstIndex + 1);
firstIndex = lastIndex + 1;
}
return res;
}