2022-8-5 笔试练习-下午场

剑指 Offer II 035. 最小时间差

难度中等

给定一个 24 小时制(小时:分钟 "HH:MM")的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。

 1 class Solution {
 2     public int findMinDifference(List<String> timePoints) {
 3         int n=timePoints.size();
 4         int[] time=new int[n];
 5         for (int i=0;i<n;i++){
 6             String s=timePoints.get(i);
 7             time[i]=Integer.valueOf(s.substring(0,2))*60+Integer.valueOf(s.substring(3));
 8             //System.out.println(time[i]);
 9         }
10         Arrays.sort(time);
11         int ans=Integer.MAX_VALUE;
12         for (int i=0;i<n;i++){
13             int t=Math.abs(time[(i+1)%n]-time[i]);
14             t=t>720?1440-t:t;
15             ans=Math.min(ans,t);
16             //System.out.println(t);
17         }
18         return ans;
19     }
20 }

思路:把时间转化成数字,再求解。

 

2357. 使数组中所有元素都等于零

难度简单

给你一个非负整数数组 nums 。在一步操作中,你必须:

  • 选出一个正整数 x ,x 需要小于或等于 nums 中 最小 的 非零 元素。
  • nums 中的每个正整数都减去 x

返回使 nums 中所有元素都等于 0 需要的 最少 操作数。

 1 class Solution {
 2     public int minimumOperations(int[] nums) {
 3         int cnt=0,n=nums.length,index=0;
 4         Arrays.sort(nums);
 5         while (nums[n-1]!=0){
 6             while (nums[index]==0) index++;
 7             int t=nums[index];
 8             for (int i=index;i<n;i++){
 9                 nums[i]-=t;
10             }
11             index++;
12             cnt++;
13         }
14         return cnt;
15     }
16 }

思路:数据量很小,直接模拟过程。

每次操作可以让一个非0的变成0,相当于求非0数字的集合数量。

 

2358. 分组的最大数量

难度中等

给你一个正整数数组 grades ,表示大学中一些学生的成绩。你打算将 所有 学生分为一些 有序 的非空分组,其中分组间的顺序满足以下全部条件:

  • 第 i 个分组中的学生总成绩 小于 第 (i + 1) 个分组中的学生总成绩,对所有组均成立(除了最后一组)。
  • 第 i 个分组中的学生总数 小于 第 (i + 1) 个分组中的学生总数,对所有组均成立(除了最后一组)。

返回可以形成的 最大 组数。

class Solution {
    public int maximumGroups(int[] grades) {
        int n=grades.length;
        int cnt=0,i=1;
        while (n>=i){
            n-=i++;
            cnt++;
        }
        return cnt;
    }
}

思路:贪心原则,在数组排过序后,让小的分数优先形成组,只要人数加1可以保证总分数一定满足要求。所以直接1,2,3...分组,分不了新的就在最后一组。

 

2359. 找到离给定两个节点最近的节点

难度中等

给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,每个节点 至多 有一条出边。

有向图用大小为 n 下标从 0 开始的数组 edges 表示,表示节点 i 有一条有向边指向 edges[i] 。如果节点 i 没有出边,那么 edges[i] == -1 。

同时给你两个节点 node1 和 node2 。

请你返回一个从 node1 和 node2 都能到达节点的编号,使节点 node1 和节点 node2 到这个节点的距离 较大值最小化。如果有多个答案,请返回 最小 的节点编号。如果答案不存在,返回 -1 。

注意 edges 可能包含环。

 1 class Solution {
 2     public int closestMeetingNode(int[] edges, int node1, int node2){
 3 
 4         int n=edges.length;
 5         int[] dis1=new int[n];
 6         int[] dis2=new int[n];
 7         dfs(node1,edges,dis1);
 8         dfs(node2,edges,dis2);
 9         int ans=Integer.MAX_VALUE;
10         int node=-1;
11         for (int i=0;i<dis1.length;i++){
12             if (dis1[i]!=Integer.MAX_VALUE&&dis2[i]!=Integer.MAX_VALUE){
13                 int temp=Math.max(dis1[i],dis2[i]);
14                 if (temp<ans){
15                     ans=temp;
16                     node=i;
17                 }
18             }
19         }
20         return node;
21 
22     }
23 
24     public void dfs(int node,int[] edges,int[] dis){
25         Arrays.fill(dis,Integer.MAX_VALUE);
26         dis[node]=0;
27         Set<Integer> set=new HashSet<>();
28         int cnt=1;
29         while (edges[node]!=-1&&!set.contains(edges[node])) {
30             int nextnode = edges[node];
31             dis[nextnode] = Math.min(cnt,dis[nextnode]);
32             set.add(nextnode);
33             cnt++;
34             node = nextnode;
35         }
36     }
37 }

思路:分别遍历两个节点,计算连通的点的距离。然后比较出答案。

posted on 2022-08-05 17:34  阿ming  阅读(22)  评论(0编辑  收藏  举报

导航