内容来自刘宇波老师算法与数据结构体系课
1、二分查找法
| |
| |
| |
| public class BinarySearch { |
| |
| private BinarySearch() { |
| } |
| |
| |
| |
| |
| public static <E extends Comparable<E>> int searchR(E[] data, E target) { |
| return searchR(data, 0, data.length - 1, target); |
| } |
| |
| private static <E extends Comparable<E>> int searchR(E[] data, int l, int r, E target) { |
| if (l > r) return -1; |
| |
| int mid = l + (r - l) / 2; |
| if (data[mid].compareTo(target) == 0) return mid; |
| |
| if (data[mid].compareTo(target) < 0) return searchR(data, mid + 1, r, target); |
| return searchR(data, l, mid - 1, target); |
| } |
| |
| |
| |
| |
| public static <E extends Comparable<E>> int search(E[] data, E target) { |
| int l = 0; |
| int r = data.length - 1; |
| int mid; |
| |
| |
| |
| while (l <= r) { |
| mid = l + (r - l) / 2; |
| if (data[mid].compareTo(target) == 0) return mid; |
| if (data[mid].compareTo(target) < 0) l = mid + 1; |
| else r = mid - 1; |
| } |
| |
| return -1; |
| } |
| } |
2、Ceil 上界
| public class Ceil { |
| |
| private Ceil() { |
| } |
| |
| |
| |
| |
| private static <E extends Comparable<E>> int upper(E[] data, E target) { |
| int l = 0; |
| int r = data.length; |
| int mid; |
| |
| |
| |
| while (l < r) { |
| mid = l + (r - l) / 2; |
| if (data[mid].compareTo(target) > 0) r = mid; |
| else l = mid + 1; |
| } |
| |
| return r; |
| } |
| |
| |
| |
| |
| |
| public static <E extends Comparable<E>> int ceilR(E[] data, E target) { |
| int upper = upper(data, target); |
| if (upper - 1 >= 0 && data[upper - 1].compareTo(target) == 0) return upper - 1; |
| return upper; |
| } |
| |
| |
| |
| |
| |
| public static <E extends Comparable<E>> int ceilL(E[] data, E target) { |
| int l = 0; |
| int r = data.length; |
| int mid; |
| |
| |
| |
| while (l < r) { |
| mid = l + (r - l) / 2; |
| if (data[mid].compareTo(target) >= 0) r = mid; |
| else l = mid + 1; |
| } |
| |
| return r; |
| } |
| } |
3、Floor 下界
| public class Floor { |
| |
| private Floor() { |
| } |
| |
| |
| |
| |
| private static <E extends Comparable<E>> int lower(E[] data, E target) { |
| int l = -1; |
| int r = data.length - 1; |
| int mid; |
| |
| |
| |
| while (l < r) { |
| mid = l + (r - l + 1) / 2; |
| if (data[mid].compareTo(target) < 0) l = mid; |
| else r = mid - 1; |
| } |
| |
| return l; |
| } |
| |
| |
| |
| |
| |
| public static <E extends Comparable<E>> int floorL(E[] data, E target) { |
| int lower = lower(data, target); |
| if (lower + 1 < data.length && data[lower + 1].compareTo(target) == 0) return lower + 1; |
| return lower; |
| } |
| |
| |
| |
| |
| |
| public static <E extends Comparable<E>> int floorR(E[] data, E target) { |
| int l = -1; |
| int r = data.length - 1; |
| int mid; |
| |
| |
| |
| while (l < r) { |
| mid = l + (r - l + 1) / 2; |
| if (data[mid].compareTo(target) <= 0) l = mid; |
| else r = mid - 1; |
| } |
| |
| return l; |
| } |
| } |
4、力扣问题
| 如果问题有明显的边界,就可以用二分查找法在这个边界去搜索问题的解 |
4.1、爱吃香蕉的珂珂
875 - 爱吃香蕉的珂珂
| public class MinEatingSpeed { |
| |
| |
| |
| |
| |
| public static int minEatingSpeed(int[] piles, int h) { |
| int speedL = 1; |
| int speedR = Arrays.stream(piles).max().getAsInt(); |
| int speedMid; |
| |
| |
| |
| |
| while (speedL < speedR) { |
| speedMid = speedL + (speedR - speedL) / 2; |
| int time = getEatingTime(piles, speedMid); |
| if (time <= h) speedR = speedMid; |
| else speedL = speedMid + 1; |
| } |
| |
| return speedR; |
| } |
| |
| private static int getEatingTime(int[] piles, int speed) { |
| int times = 0; |
| for (int pile : piles) { |
| times += pile / speed + (pile % speed == 0 ? 0 : 1); |
| } |
| return times; |
| } |
| |
| public static void main(String[] args) { |
| int[] piles1 = {3, 6, 7, 11}; |
| System.out.println(minEatingSpeed(piles1, 8)); |
| |
| int[] piles2 = {30, 11, 23, 4, 20}; |
| System.out.println(minEatingSpeed(piles2, 5)); |
| } |
| } |
4.2、在 D 天内送达包裹的能力
1011 - 在 D 天内送达包裹的能力
| public class ShipWithinDays { |
| |
| public static int shipWithinDays(int[] weights, int days) { |
| int capacityL = Arrays.stream(weights).max().getAsInt(); |
| int capacityR = Arrays.stream(weights).sum(); |
| int capacityMid; |
| |
| |
| |
| |
| while (capacityL < capacityR) { |
| capacityMid = capacityL + (capacityR - capacityL) / 2; |
| int times = getShipTime(weights, capacityMid); |
| if (times <= days) capacityR = capacityMid; |
| else capacityL = capacityMid + 1; |
| } |
| |
| return capacityR; |
| } |
| |
| private static int getShipTime(int[] weights, int maxCapacity) { |
| int times = 0; |
| int hasCapacity = 0; |
| for (int weight : weights) { |
| if (hasCapacity + weight <= maxCapacity) hasCapacity += weight; |
| else { |
| times++; |
| hasCapacity = weight; |
| } |
| } |
| return times + 1; |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步