LeetCode刷题 day9

目录

  • [1. 一周中的第几天](#1. 一周中的第几天)
  • [2. 公交站间的距离](#2. 公交站间的距离)
  • [3. "气球" 的最大数量](#3. “气球” 的最大数量)
  • [4. 最小绝对差](#4. 最小绝对差)

1. 一周中的第几天

给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。

输入为三个整数:day、month 和 year,分别表示日、月、年。

您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}。

注意:1971 年 1 月 1 日是星期五。

示例 1:

输入:day = 31, month = 8, year = 2019

输出:"Saturday"
示例 2:

输入:day = 18, month = 7, year = 1999

输出:"Sunday"
示例 3:

输入:day = 15, month = 8, year = 1993

输出:"Sunday"

思路

本质是从1971年开始数,数到当前年份的前一年,其中要区分平年和闰年,然后当前年份又开始数,数到当前月份的前一个月份,注意月份是否大于2月且当前年份是平年还是闰年,最后加上天数,然后除以7天得到的余数就是星期几

java 复制代码
class Solution {
    private static final int[] Month = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    private static final String[] Week = {"Thursday","Friday", "Saturday","Sunday", "Monday", "Tuesday", "Wednesday"};
    public String dayOfTheWeek(int day, int month, int year) {
        int count = 0;
        for(int i=1971;i<year;i++){
            if(isLeapYear(i)){
                count+=366;
            }else{
                count+=365;
            }
        }
        for(int i=1;i<month;i++){
            count += Month[i];
        }
        if(month>2&&isLeapYear(year)){
            count++;
        }
        count+= day;
        return Week[count%7];
    }
    private boolean isLeapYear(int year){
        return year%400==0||(year%100!=0&&year%4==0);
    }
}

时间复杂度: O(C),其中 C 为一年中的月份数 12。仅需常量时间的数学计算。

空间复杂度: O(C),其中 C 为一年中的月份数 12。仅需常量空间的数组。

2. 公交站间的距离

环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为 (i + 1) % n 的车站之间的距离。

环线上的公交车都可以按顺时针和逆时针的方向行驶。

返回乘客从出发点 start 到目的地 destination 之间的最短距离。
示例1:

输入:distance = [1,2,3,4], start = 0, destination = 1

输出:1

解释:公交站 0 和 1 之间的距离是 1 或 9,最小值是 1。
示例2:

输入:distance = [1,2,3,4], start = 0, destination = 2

输出:3

解释:公交站 0 和 2 之间的距离是 3 或 7,最小值是 3。
示例3:

输入:distance = [1,2,3,4], start = 0, destination = 3

输出:4

解释:公交站 0 和 3 之间的距离是 6 或 4,最小值是 4。

思路

一是理解distance[i]表示i到(i+1)%n站的距离,二是顺时针和逆时针和为环线总距离,因此只要计算顺时针和总距离即可

java 复制代码
class Solution {
    public int distanceBetweenBusStops(int[] distance, int start, int destination) {
        int totalDis = 0;
        int dis = 0;
        int l = Math.min(start,destination),r=Math.max(start,destination);
        for(int i=0;i<distance.length;i++){
            totalDis += distance[i];

            if(i>=l&&i<r){
                dis+=distance[i];
            }
        }
        return Math.min(totalDis-dis,dis);
    }
}

时间复杂度: O(n),n表示数组长度
空间复杂度: O(1)

3. "气球" 的最大数量

给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。

字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon"。

示例 1:

输入:text = "nlaebolko"

输出:1

示例 2:

输入:text = "loonbalxballpoon"

输出:2

示例3:

输入:text = "leetcode"

输出:0
思路

直接统计所有字母数量,再找出balon的数量的最小值,其中l和o需要除以2

java 复制代码
class Solution {
  public int maxNumberOfBalloons(String text) {
        // 1. 初始化数组统计26个小写字母的频次
        int[] count = new int[26];
        for (char c : text.toCharArray()) {
            count[c - 'a']++;
        }

        // 2. 提取 balloon 所需字符的频次
        int b = count[1];  // 'b' - 'a' = 1
        int a = count[0];  // 'a' - 'a' = 0
        int l = count[11]; // 'l' - 'a' = 11
        int o = count[14]; // 'o' - 'a' = 14
        int n = count[13]; // 'n' - 'a' = 13

        // 3. l和o各需要2个,所以除以2取整数
        l /= 2;
        o /= 2;

        // 4. 最小值就是能拼凑的最大数量
        return Math.min(Math.min(Math.min(b, a), l), Math.min(o, n));
    }
}

4. 最小绝对差

给你个整数数组 arr,其中每个元素都 不相同。

请你找到所有具有最小绝对差的元素对,并且按升序的顺序返回。

每对元素对 [a,b] 如下:

a , b 均为数组 arr 中的元素

a < b

b - a 等于 arr 中任意两个元素的最小绝对差

示例 1:

输入:arr = [4,2,1,3]

输出:[[1,2],[2,3],[3,4]]

示例 2:

输入:arr = [1,3,6,10,15]

输出:[[1,3]]

示例 3:

输入:arr = [3,8,-10,23,19,-4,-14,27]

输出:[[-14,-10],[19,23],[23,27]]

思路

先排序再求相邻元素的差值即可,这里需要关注的是什么时候用什么方法解题,培养题感,知道什么时候用排序,什么时候不需要排序。本题中要找到最小绝对值的元素对,肯定要比较所有有序元素相邻两个的差值,然后取最小值,时间复杂度不可能小于排序时间复杂度,两两遍历的时间复杂度是O(n^2)

java 复制代码
class Solution {
    public List<List<Integer>> minimumAbsDifference(int[] arr) {
        Arrays.sort(arr);
        int minDis = Integer.MAX_VALUE;
        List<List<Integer>> ans = new ArrayList<>();
        for(int i=1;i<arr.length;i++){
            int dis = arr[i]-arr[i-1];
            if(dis<minDis){
                ans.clear();
                minDis = dis;
                ans.add(Arrays.asList(arr[i-1],arr[i])); 
            }else if(dis==minDis){
                ans.add(Arrays.asList(arr[i-1],arr[i])); 
            }
        }
        return ans;
    }
}

时间复杂度: O(nlogn)
空间复杂度: O(n)

相关推荐
bIo7lyA8v2 小时前
算法稳定性分析中的随机扰动建模的技术9
算法
忧郁的Mr.Li2 小时前
JAVA工具类---PDF电子签章工具类
java·pdf
谢白羽2 小时前
vllm抢占机制详解
算法·vllm
Hello--_--World2 小时前
Vue2的 双端 diff算法 与 Vue3 的 快速diff 算法
前端·vue.js·算法
零二年的冬2 小时前
epoll详解
java·linux·开发语言·c++·链表
凭君语未可2 小时前
Java 中的接口是什么
java·开发语言
XiYang-DING2 小时前
【Java】二叉树
java·开发语言·数据结构
坚持编程的菜鸟2 小时前
The Blocks Problem
数据结构·c++·算法
2301_822703202 小时前
Flutter 框架跨平台鸿蒙开发 - 家庭时间胶囊应用
算法·flutter·华为·图形渲染·harmonyos·鸿蒙