942. 增减字符串匹配 / 剑指 Offer II 034. 外星语言是否排序 / 剑指 Offer II 035. 最小时间差

这篇博客探讨了三种不同的编程问题,涉及字符串处理和排序算法。第一题是增减字符串匹配,通过模拟实现递增和递减过程找到匹配的数组。第二题是外星语言是否排序,利用模拟方法判断单词是否按特定字母表排序。第三题是最小时间差,通过排序和鸽巢原理找到列表中最小的时间差。这些题目展示了在实际问题中应用基础算法的能力。
摘要由CSDN通过智能技术生成

942. 增减字符串匹配【简单题】【每日一题】

思路:【模拟】

由题意可知,要返回的数组长度为 n+1 且每一个元素的取值范围是 [0,n] ,又 当前i位置字符I对应 数组 i 位置元素比它右侧位置小 ,当前i位置字符 D 对应 数组i位置元素比它右侧位置大。
我们可以理解为I–> 递增 ;D -->递减,我们设递增起始值 left = 0,递减起始值 right = n,那么从左到右依次遍历字符串,遇到I就将对应位置 数组元素赋值为left,并使left自增1,遇到D就将对应位置 数组元素赋值为 right,并使right 自减1,最后将数组最后的未赋值位置赋值为此时的leftright,都可以。

代码:

class Solution {
    public int[] diStringMatch(String s) {
        int n = s.length();
        int[] ans = new int[n+1];
        char[] chars = s.toCharArray();
        int left = 0,right = n,i = 0;
        for (char c : chars) {
            if (c == 'I'){
                ans[i++] = left++;
            }else {
                ans[i++] = right--;
            }
        }
        ans[i] = right;
        return ans;
    }
}

剑指 Offer II 034. 外星语言是否排序【简单题】

思路:【模拟】

使用int类型数组 dic 存储给定字母表顺序,然后以单词列表第1个单词为标准单词,从第2个单词开始依次判断待判断单词与标准单词是否满足字典序排序,是则将待判断单词更新为标准单词继续下一个单词的判断,不是则函数返回false

代码:

class Solution {
    public boolean isAlienSorted(String[] words, String order) {
        //使用 dic 记录字母表顺序
        int[] dic = new int[26];
        for (int i = 0; i < 26; i++) {
            dic[order.charAt(i)-'a'] = i;
        }
        //锚定一个起始单词
        String word = words[0];
        //求出起始单词的长度和单词列表的长度
        int len = word.length(),n = words.length;
        //从起始单词的下一个开始,依次遍历单词列表
        for (int i = 1; i < n; i++) {
            //定义单词顺序是否正确的标志位 初始为false
            boolean flag = false;
            //以起始单词长度为标准
            for (int j = 0; j < len; j++) {
                //如果 j >= 待判断单词的长度 说明待判断单词已遍历完毕,而此时标准单词仍有字符尚未判断,这种情况说明待判断单词与标准单词是不符合字典序排序的,函数返回false
                if (j >= words[i].length()){
                    return false;
                }
                //定义当前位置标准单词的字符 left 当前位置待判断单词的字符 right
                char left = word.charAt(j),right = words[i].charAt(j);
                //如果left = right 则继续判断下一个位置,否则
                if (left != right){
                    //当left != right 是,left 的字典序只能比right小,否则直接返回false
                    if (dic[left-'a'] < dic[right-'a']){
                        //left的字典序比right小,那么这两个单词已经判断完毕,符合题意,将标志位flag置为true,退出判断循环
                        flag = true;
                        break;
                    }else {
                        return false;
                    }
                }
            }
            //如果flag为true,说明当前待判断单词与标准单词的字典序排序是正确的,否则,说明遍历完了依然全部相等,即待判断单词与标准单词是相等的,此时甚至标准单词都不用更新,直接进行下一个单词的判断即可
            if (flag){
                //字典序排序正确时,将标准单词更新为待判断单词,然后判断下一个单词
                word = words[i];
            }
        }
        //单词列表只有一个单词时,不会走上述判断循环,函数直接返回true  当所有的循环都走完,依然没有返回false,说明单词列表是严格按字典序排序的,此时返回true
        return true;
    }
}


剑指 Offer II 035. 最小时间差【中等题】

思路:【排序+鸽巢原理】

首先通过鸽巢原理将数据量压缩;当数据量大于1440时,必然会有重复的时间,此时最小时间差必然是0,直接返回0
然后将timePoints排序,这样最小时间差必然出现在两个相邻的时间,或者首尾时间之间。

代码:

class Solution {
    public int findMinDifference(List<String> timePoints) {
        int timeSize = timePoints.size();
        if (timeSize > 1440){//一天总共就1440分钟,如果timePoints中的数据超过1440,那么必然有至少两个时间是重复的,最小时间差必然是0,直接返回0
            return 0;
        }
        //对timePoints进行排序,这样的话最小时间差必然出现在两个相邻时间中,或者首尾时间中
        Collections.sort(timePoints);
        int min = Integer.MAX_VALUE;
        String pre = timePoints.get(0);
        for (int i = 1; i < timeSize; i++) {
            int minute = getMinutes(timePoints.get(i),pre);
            min = Math.min(min,minute);//求相邻时间的时间差,并更新min
            pre = timePoints.get(i);
        }
        min = Math.min(min,getMinutes(timePoints.get(0),pre)+1440);//求首尾时间的时间差,并更新min
        return min;
    }
    public int getMinutes(String time1,String time2){
        int m1 = ((time1.charAt(0)-'0')*10 + (time1.charAt(1)-'0')) * 60 + (time1.charAt(3)-'0') * 10 + (time1.charAt(4)-'0');
        int m2 = ((time2.charAt(0)-'0')*10 + (time2.charAt(1)-'0')) * 60 + (time2.charAt(3)-'0') * 10 + (time2.charAt(4)-'0');
        return m1-m2;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值