2022-2-9数学day3

题1:

给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +- 以及 * 。

示例 1:

输入: "2-1-1"
输出: [0, 2]
解释: 
((2-1)-1) = 0 
(2-(1-1)) = 2

示例 2:

输入: "2*3-4*5"
输出: [-34, -14, -10, -10, 10]
解释: 
(2*(3-(4*5))) = -34 
((2*3)-(4*5)) = -14 
((2*(3-4))*5) = -10 
(2*((3-4)*5)) = -10 
(((2*3)-4)*5) = 10
 1 class Solution {
 2     public List<Integer> diffWaysToCompute(String expression) {
 3         List<Integer> res=new LinkedList<>();
 4         for (int i=0;i<expression.length();i++){
 5             char c=expression.charAt(i);
 6             if (c=='+'||c=='-'||c=='*') {
 7                 List<Integer> left=diffWaysToCompute(expression.substring(0,i));
 8                 List<Integer> right=diffWaysToCompute(expression.substring(i+1));
 9                 for (int x:left) {
10                     for (int y:right){
11                         if (c=='+') res.add(x+y);
12                         else if (c=='*') res.add(x*y);
13                         else res.add(x-y);
14                     }
15                 }
16             }
17         }
18         if (res.isEmpty()) {
19             res.add(Integer.parseInt(expression));
20         }
21         return res;
22     }
23 }

思路:分治思想。以符号为分割点,将问题划分为前后两个小字符串的解集,然后遍历得到所有的可能性。需要注意,如果没有新的计算结果说明已经划分到具体的数字,直接添加数字即可。

题2:

在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。

说明: 

  • 如果题目有解,该答案即为唯一答案。
  • 输入数组均为非空数组,且长度相同。
  • 输入数组中的元素均为非负数。

示例 1:

输入: 
gas  = [1,2,3,4,5]
cost = [3,4,5,1,2]

输出: 3

解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。

示例 2:

输入: 
gas  = [2,3,4]
cost = [3,4,3]

输出: -1

解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n=gas.length;
        int start=0,sum=0,min=Integer.MAX_VALUE;
        for (int i=0;i<n;i++) {
            sum+=gas[i]-cost[i];
            if (sum<min) {
                min=sum;
                start=i+1;
            }
        }
        if (sum<0) return -1;
        return start==n?0:start;
    }
}

思路:对于每一次出发 都会消耗gas-cost的量,将消耗量累加起来,最低的时候出发是必定能走一圈的。其次判断累加值是不是为负数,此时必定走不完。由于是环形,起点为n要返回0;

题3:

你将会获得一系列视频片段,这些片段来自于一项持续时长为 time 秒的体育赛事。这些片段可能有所重叠,也可能长度不一。

使用数组 clips 描述所有的视频片段,其中 clips[i] = [starti, endi] 表示:某个视频片段开始于 starti 并于 endi 结束。

甚至可以对这些片段自由地再剪辑:

  • 例如,片段 [0, 7] 可以剪切成 [0, 1] + [1, 3] + [3, 7] 三部分。

我们需要将这些片段进行再剪辑,并将剪辑后的内容拼接成覆盖整个运动过程的片段([0, time])。返回所需片段的最小数目,如果无法完成该任务,则返回 -1 。

 

示例 1:

输入:clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], time = 10
输出:3
解释:
选中 [0,2], [8,10], [1,9] 这三个片段。
然后,按下面的方案重制比赛片段:
将 [1,9] 再剪辑为 [1,2] + [2,8] + [8,9] 。
现在手上的片段为 [0,2] + [2,8] + [8,10],而这些覆盖了整场比赛 [0, 10]。

示例 2:

输入:clips = [[0,1],[1,2]], time = 5
输出:-1
解释:
无法只用 [0,1] 和 [1,2] 覆盖 [0,5] 的整个过程。

示例 3:

输入:clips = [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2,5],[2,6],[3,4],[4,5],[5,7],[6,9]], time = 9
输出:3
解释: 
选取片段 [0,4], [4,7] 和 [6,9] 。

示例 4:

输入:clips = [[0,4],[2,8]], time = 5
输出:2
解释:
注意,你可能录制超过比赛结束时间的视频。

 

提示:

  • 1 <= clips.length <= 100
  • 0 <= starti <= endi <= 100
  • 1 <= time <= 100
 1 class Solution {
 2     public int videoStitching(int[][] clips, int time) {
 3         Arrays.sort(clips,(a,b)->{
 4             if (a[0]==b[0]) return b[1]-a[1];
 5             else return a[0]-b[0];
 6         });
 7         int res=0,curr=0,next=0;
 8         int index=0,n=clips.length;
 9         while (index<n&&clips[index][0]<=curr){
10             while (index<n&&clips[index][0]<=curr){
11                 next=Math.max(next,clips[index][1]);
12                 index++;
13             }
14             res++;
15             curr=next;
16             if (next>=time) return res;
17         }
18         return -1;
19     }
20 }

思路:贪心。将所有区间按照起点升序,终点降序的方法排序。在起点满足的情况下,优先挑选终点最长的,以该终点为新起点,在不超过新起点的所有区间内同样找最长的区间。

posted on 2022-02-09 20:40  阿ming  阅读(26)  评论(0)    收藏  举报

导航