4月26日划分字母区间+合并区间

736.划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s

返回一个表示每个字符串片段的长度的列表。

提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成

思路

这题我自己没想出来,刚开始想的是遍历每个字母,遍历到了就加进哈希表,然后从后往前找第一个重复字母,然后再找下一个字母,但是始终没想明白怎么判断结束。

题解的思路是定义一个end来存储当前区间的结束位置,每次遍历判断end后面是否有和前面字母重复的,有的话就更新end,如果遍历到end就把当前区间长度加入答案。

还用到了一个技巧就是定义一个存放26个字母最后出现位置的数组,然后从前往后遍历数组,更新每个字母最后出现的位置,这样之后我们在遍历时就不需要再去从后往前找第一个重复字母。

代码

java 复制代码
    class Solution {
        public List<Integer> partitionLabels(String s) {
            List<Integer> ans=new ArrayList<>();
            int[] last=new int[26];
            for(int i=0;i<s.length();i++){
                last[s.charAt(i)-'a']=i;
            }
            int start=0,end=0;
            for(int i=0;i<s.length();i++){
                end=Math.max(end,last[s.charAt(i)-'a']);
                if(i==end){
                    ans.add(end-start+1);
                    start=end+1;
                }
            }     
            return ans;
        }
    }

56.合并区间

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间

思路

看到这种区间类的题目我的第一反应是先排序,这里不用管相同的时候第二个元素怎么排,反正肯定会合并为一个区间。然后遍历,记录start和end作为合并的区间,首先初始化为[0][0]和[0][1],然后往后遍历,如果遍历到的元素的start小于等于当前的end,则更新end为该元素end与当前end之间较大值,如果大于则将当前start和end加入答案,并更新start和end为该元素的。若已经遍历到最后一个元素,则在处理完之后将start和end再加入答案。

代码

java 复制代码
class Solution {
        public int[][] merge(int[][] intervals) {
            if(intervals.length==1){
                return intervals;
            }
            List<int[]> ans=new ArrayList<int[]>();
            Arrays.sort(intervals, new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {
                    return o1[0]-o2[0];
                }
            });
            int start=intervals[0][0],end=intervals[0][1];
            for(int i=1;i<intervals.length;i++){
                if(intervals[i][0]<=end){
                    end=Math.max(end,intervals[i][1]);
                }else  {
                    ans.add(new int[]{start,end});
                    start=intervals[i][0];
                    end=intervals[i][1];
                }
                if(i==intervals.length-1){
                        ans.add(new int[]{start,end});
                    }
            }
            return ans.toArray(new int[ans.size()][]);
        }
    }

总结

最近几天的刷题有点刷上瘾了,这种自己独立思考写出代码然后ac的感觉确实很棒,后天就要进入动态规划了,希望不被虐死吧

相关推荐
ChoSeitaku34 分钟前
链表循环及差集相关算法题|判断循环双链表是否对称|两循环单链表合并成循环链表|使双向循环链表有序|单循环链表改双向循环链表|两链表的差集(C)
c语言·算法·链表
Fuxiao___43 分钟前
不使用递归的决策树生成算法
算法
我爱工作&工作love我1 小时前
1435:【例题3】曲线 一本通 代替三分
c++·算法
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
workflower1 小时前
数据结构练习题和答案
数据结构·算法·链表·线性回归
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法
Sunyanhui12 小时前
力扣 二叉树的直径-543
算法·leetcode·职场和发展
一个不喜欢and不会代码的码农2 小时前
力扣105:从先序和中序序列构造二叉树
数据结构·算法·leetcode
前端郭德纲2 小时前
浏览器是加载ES6模块的?
javascript·算法
SoraLuna2 小时前
「Mac玩转仓颉内测版10」PTA刷题篇1 - L1-001 Hello World
算法·macos·cangjie