题目链接

我们可以通过生成辅助数组来验证良好出发点

  1. int[]h

这个数组的长度和cost数组长度一致,且这个数组的每个元素的生成逻辑是:

  1. h[i]=gas[i]-cost[i];

h(i) 往后累加,并回到i位置,不出现负数,就是良好出发点 ,这个i位置就是良好出发点

  1. // 暴力解法 O(N^2)
  2. public static int canCompleteCircuit3(int[] gas, int[] cost) {
  3. int n = gas.length;
  4. int[] h = new int[n];
  5. for (int i = 0; i < n; i++) {
  6. h[i] = gas[i] - cost[i];
  7. }
  8. // 标记良好出发点的位置,开始是-1,说明没有找到良好出发点
  9. int good = -1;
  10. // h[i] 一直往后累加,累加和记录在preSum中,回到本身,如果不出现负数,i位置就是良好出发点
  11. int preSum;
  12. for (int i = 0; i < n; i++) {
  13. preSum = h[i];
  14. for (int j = i + 1; j < n + i + 1; j++) {
  15. if (preSum < 0) {
  16. break;
  17. }
  18. // int index = j % n
  19. int index = j > n - 1 ? j - n : j;
  20. preSum += h[index];
  21. }
  22. if (preSum >= 0) {
  23. good = i;
  24. }
  25. }
  26. return good;
  27. }

首先,我们还是需要生成h[i]数组

  1. h[i]=gas[i]-cost[i];

假设生成的h[i]数组如下:

  1. [1,-1,0,3,-1]

我们生成其累加和数组preSum[i]

  1. [1,0,0,3,2]

用这个累加和数组在和h[i]数组相加,得到一个两倍长度的数组

  1. [1,0,0,3,2,3,2,2,5,4]

求针对这个数组,滑动窗口为n(n为原数组长度)的最小值,如果第i个窗口内的最小值减去窗口前一个位置的值,如果小于0,则i号位置不是良好出发点

比如

L…L + n – 1 是第x个窗口,最小值m,

如果 m – num[L-1] >= 0 则x是良好出发点

反之,则x不是良好出发点, 完整代码:

  1. public static int canCompleteCircuit(int[] gas, int[] cost) {
  2. int len = gas.length;
  3. int doubleLen = len << 1;
  4. int[] h = new int[doubleLen];
  5. h[0] = gas[0] - cost[0];
  6. for (int i = 1; i < doubleLen; i++) {
  7. if (i < len) {
  8. h[i] = gas[i] - cost[i];
  9. h[i] += h[i - 1];
  10. }
  11. if (i >= len) {
  12. h[i] = h[len - 1] + h[i - len];
  13. }
  14. }
  15. LinkedList<Integer> qMin = new LinkedList<>();
  16. int r = 0;
  17. int index = 0;
  18. while (r < doubleLen) {
  19. while (!qMin.isEmpty() && h[qMin.peekLast()] >= h[r]) {
  20. qMin.pollLast();
  21. }
  22. qMin.addLast(r);
  23. if (qMin.peekFirst() == r - len) {
  24. qMin.pollFirst();
  25. }
  26. if (r >= len - 1) {
  27. if (r == len - 1) {
  28. if (h[qMin.peekFirst()] >= 0) {
  29. return index;
  30. }
  31. } else {
  32. if (h[qMin.peekFirst()] - h[r - len] >= 0) {
  33. return index;
  34. }
  35. }
  36. index++;
  37. }
  38. r++;
  39. }
  40. return -1;
  41. }

TODO

算法和数据结构笔记

版权声明:本文为greyzeng原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/greyzeng/p/14466197.html