Hard-题目28:57. Insert Interval

本文介绍了一个关于区间集合的问题,即如何插入一个新的区间并进行合并化简。通过对比Merge Intervals问题,提供了一种解决方案,包括定义区间比较器,并实现区间插入和合并的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目原文:
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:
Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].

Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16].

This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].
题目大意:
给出一个区间集合,插入一个区间并化简。
题目分析:
跟前面的Hard-题目22:56. Merge Intervals是一回事,但是数据强了一些,要把数组开到40000.
源码:(language:java)

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    private class IntervalComparator implements Comparator<Interval> {
        @Override
        public int compare(Interval o1, Interval o2) {
            // TODO Auto-generated method stub
            if(o1.start<o2.start)
                return -1;
            else if(o1.start>o2.start)
                return 1;
            else {
                if(o1.end<o2.end)
                    return -1;
                else if(o1.end>o2.end)
                    return 1;
                else {
                    return 0;
                }
            }
        }

    }
    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
        intervals.add(newInterval);
        List<Interval> temp = merge(intervals);
        Collections.sort(temp, new IntervalComparator());
        return temp;
    }
    public List<Interval> merge(List<Interval> intervals) {
        boolean[] x = new boolean[40000];
        boolean[] dots = new boolean[40000];
        int max = Integer.MIN_VALUE,min = Integer.MAX_VALUE;
        List<Interval> list = new ArrayList<Interval>();
        for(Interval interval : intervals) {
            for(int i=interval.start;i<interval.end;i++) {
                x[i]=true;
                if(i<min)
                    min=i;
                if(i>max)
                    max=i;
            }
        }

        int i = min;
        while(i<=max) {
            if(!x[i]) {
                i++;
                continue;
            }
            int start=i,end=start;
            while(x[end])
                end++;
            list.add(new Interval(start,end));
            i=end;

        }
        for(Interval interval : intervals) {
            int start = interval.start,end = interval.end;
            if(start==end && !dots[interval.start]) {
                dots[start] = true;
                if(start==0 && !x[0])
                    list.add(new Interval(start, end));
                else if(!x[start] && !x[start-1])
                    list.add(new Interval(start, end));
            }

        }
        return list;
    }
}

成绩:
9ms,24.58%,5ms,26.17%

<think>我们有一个JSON数据,需要按照oid作为纵轴(y轴),每个opcode分开表示,平均interval作为横轴(x轴)。这种需求通常可以用条形图(每个oid对应一组不同opcode的条形)或分组条形图(每个oid对应多个opcode的条形)来表示。由于每个oid可能有多个opcode,每个opcode有一个平均interval,因此分组条形图(GroupedBarChart)或堆叠条形图(StackedBarChart)可能合适。但根据需求,我们是要分开每个opcode,所以分组条形图更合适。另外,由于oid作为纵轴,我们可能需要横向的条形图(水平条形图),这样每个oid在纵轴上占据一行,然后每个opcode用不同颜色的条形表示,条形的长度表示平均interval。在Python中,我们可以使用Matplotlib或Seaborn来实现。这里我们选择使用Seaborn,因为它基于Matplotlib,并且提供了更高级的接口,可以更容易地绘制分组条形图(水平条形图)。但注意,Seaborn默认的条形图是垂直的,我们可以通过设置`orient='h'`来绘制水平条形图,但Seaborn的barplot函数并不直接支持分组条形图(在同一个x位置绘制多个条形),通常使用`hue`参数来分组是在同一个位置堆叠或者并排(垂直条形图并排,水平条形图上下排列),但这样可能不太直观。因此,我们可以使用Seaborn的FacetGrid,或者使用Matplotlib直接绘制。另一种方法是使用DataFrame的数据结构,然后使用Seaborn的`catplot`(分类图)来绘制,设置`kind='bar'`,并且通过`row`或`col`参数来分面,但这样可能不是在同一张图上分组。因此,我们选择使用水平条形图,每个oid对应一组条形(每个opcode一个条形),并排显示。然而,如果oid数量很多,那么分组条形图可能会很拥挤。因此,我们也可以考虑使用堆叠条形图,但堆叠条形图适合表示各个部分的总和,而我们这里每个opcode是分开的,并不需要堆叠。所以,分组条形图(并排)更合适。但是,在水平条形图中,分组条形图通常表示在同一y位置(即同一个oid)上,不同opcode的条形并排显示(水平并排,即垂直方向上有轻微偏移)。这可以通过调整条形的位置来实现。由于Seaborn没有直接提供水平分组条形图(并排)的函数,我们可以使用以下方法:1.将数据整理成DataFrame,包含三列:oid,opcode,avg_interval2.使用Matplotlib手动绘制每个条形,通过计算每个条形的位置。但Seaborn的`barplot`函数在水平方向时,可以通过`hue`参数实现分组,但它是将同一组的条形在同一个y位置上下排列(垂直方向并排),而水平条形图则是在同一y位置左右排列(水平方向并排)。实际上,Seaborn的`barplot`在设置`orient='h'`时,使用`hue`参数会自动在同一y位置的水平方向并排显示不同hue的条形。因此,我们可以这样:使用Seaborn的`barplot`,设置x为平均interval,y为oid,hue为opcode,并设置`orient='h'`(实际上,当我们指定x和y时,Seaborn会自动判断方向,如果y是类别型,就会画水平条形图)。然后通过`hue`参数,每个oid上会有多个不同颜色的条形(代表不同的opcode),并排显示。具体步骤:1.读取JSON数据(假设数据是一个列表,每个元素是一个记录,包含oid,opcode,avg_interval)2.转换为pandasDataFrame3.使用Seaborn的barplot绘制示例代码:假设我们有如下的JSON数据:[{"oid":"obj1","opcode":"read","avg_interval":10},{"oid":"obj1","opcode":"write","avg_interval":20},{"oid":"obj2","opcode":"read","avg_interval":15},{"oid":"obj2","opcode":"write","avg_interval":25}]我们将这个数据转换为DataFrame,然后:注意:由于oid作为纵轴,我们希望每个oid在y轴上,所以y轴应该是oid,x轴是avg_interval,然后用不同的颜色表示opcode。代码示例:```pythonimportpandasaspdimportseabornassnsimportmatplotlib.pyplotasplt#假设data是读取的JSON数据data=[{"oid":"obj1","opcode":"read","avg_interval":10},{"oid":"obj1","opcode":"write","avg_interval":20},{"oid":"obj2","opcode":"read","avg_interval":15},{"oid":"obj2","opcode":"write","avg_interval":25}]df=pd.DataFrame(data)#设置Seaborn样式sns.set(style="whitegrid")#创建水平条形图,y轴为oid,x轴为avg_interval,用opcode分组(颜色和并排)plt.figure(figsize=(10,6))sns.barplot(x='avg_interval',y='oid',hue='opcode',data=df,orient='h')#添加标题和标签plt.title('平均Interval按OID和Opcode分布')plt.xlabel('平均Interval')plt.ylabel('OID')#显示图例plt.legend(title='Opcode')plt.tight_layout()plt.show()```如果oid数量很多,我们可以调整图形大小,或者考虑横向滚动(但通常建议调整图形大小或使用分页)。另外,如果opcode的数量很多,那么并排的条形可能会很拥挤,我们可以考虑以下方法:-使用堆叠条形图(但堆叠表示总和,这里每个opcode的值是独立的,堆叠可能会误导)-使用小型的多个子图(每个oid一个子图),但oid多时也不现实因此,我们暂时使用分组条形图。在前端使用D3.js的话,实现起来更灵活,但代码量较大。这里我们主要提供Python方案。如果用户需要前端方案,我们可以简要提一下D3.js的思路:1.使用SVG绘制图形区域。2.为每个oid分配一个水平位置(纵轴位置)。3.对于每个oid,根据其opcode的数量和平均interval,绘制多个矩形(每个矩形代表一个opcode),并排排列。4.添加坐标轴和图例。但鉴于用户问题没有明确指定前端还是后端,且要求了Python库,我们主要提供Python方案。根据引用[^2][^4]中提到的Seaborn和Matplotlib,我们采用上述Seaborn方案。注意:如果数据中oid是数值型,那么我们需要将其转换为字符串类型,以便作为类别处理。另外,如果同一个oid有多个相同的opcode(通常不会,但以防万一),我们可能需要先进行分组求平均(如果原始数据是多个记录,需要先按oid和opcode分组计算avg_interval的平均值)。我们的示例数据已经是一个oid和一个opcode对应一条记录(avg_interval已经是平均后的值)。如果原始数据是多个记录,则需要先聚合。例如,原始数据可能是多个记录,每个记录有oid,opcode,interval,我们需要按oid和opcode分组,然后计算interval的平均值。代码示例:```python#假设原始数据是未聚合的,例如:raw_data=[{"oid":"obj1","opcode":"read","interval":10},{"oid":"obj1","opcode":"read","interval":12},{"oid":"obj1","opcode":"write","interval":20},#...其他数据]df_raw=pd.DataFrame(raw_data)df=df_raw.groupby(['oid','opcode'])['interval'].mean().reset_index()```然后使用上面的绘图代码。最后,根据要求,我们需要生成相关问题。因此,回答如下:</think>### 使用Python可视化JSON数据 根据您的需求(以oid为纵轴、区分opcode、平均interval为横轴),以下是两种实现方案: --- #### **方案1:使用Seaborn/Matplotlib(Python)** ```python import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import json # 1. 加载JSON数据(示例结构) data = [ {"oid": "A", "opcode": "read", "avg_interval": 15}, {"oid": "A", "opcode": "write", "avg_interval": 8}, {"oid": "B", "opcode": "read", "avg_interval": 12}, {"oid": "B", "opcode": "delete", "avg_interval": 5} ] df = pd.DataFrame(data) # 2. 创建分组条形图 plt.figure(figsize=(10, 6)) sns.barplot( x="avg_interval", y="oid", hue="opcode", data=df, orient="h", # 水平条形图 palette="viridis", dodge=True # 分组并排显示 ) # 3. 美化图表 plt.title("操作码平均间隔分布 (按对象ID)") plt.xlabel("平均间隔 (ms)") plt.ylabel("对象ID (oid)") plt.legend(title="操作码", loc="lower right") plt.grid(axis="x", linestyle="--", alpha=0.7) plt.tight_layout() plt.savefig("opcode_analysis.png", dpi=300) plt.show() ``` **关键特性**: 1. **水平条形图**:`oid`作为纵轴,符合需求 2. **颜色分组**:不同`opcode`用不同颜色区分 3. **并排显示**:同一`oid`的多个`opcode`并列比较 4. **自动适配**:支持任意数量的oid和opcode组合 --- #### **方案2:使用D3.js(前端)** ```html <!DOCTYPE html> <html> <head> <script src="https://d3js.org/d3.v7.min.js"></script> <style> .bar { fill-opacity: 0.8; } .bar:hover { fill-opacity: 1; } .axis-label { font-size: 14px; } .legend-item { cursor: pointer; } </style> </head> <body> <div id="chart"></div> <script> // 1. 加载JSON数据 const data = [ {oid: "A", opcode: "read", avg_interval: 15}, {oid: "A", opcode: "write", avg_interval: 8}, {oid: "B", opcode: "read", avg_interval: 12}, {oid: "B", opcode: "delete", avg_interval: 5} ]; // 2. 设置画布 const margin = {top: 40, right: 120, bottom: 50, left: 100}; const width = 800 - margin.left - margin.right; const height = 400 - margin.top - margin.bottom; const svg = d3.select("#chart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // 3. 创建比例尺 const xScale = d3.scaleLinear() .domain([0, d3.max(data, d => d.avg_interval)]) .range([0, width]); const yScale = d3.scaleBand() .domain([...new Set(data.map(d => d.oid))]) .range([0, height]) .padding(0.2); const colorScale = d3.scaleOrdinal() .domain([...new Set(data.map(d => d.opcode))]) .range(d3.schemeCategory10); // 4. 绘制条形 const barGroups = svg.selectAll(".oid-group") .data(d3.group(data, d => d.oid)) .join("g") .attr("class", "oid-group") .attr("transform", d => `translate(0,${yScale(d[0])})`); barGroups.selectAll(".bar") .data(d => d[1]) .join("rect") .attr("class", "bar") .attr("x", 0) .attr("y", (d,i) => i * (yScale.bandwidth() / d[1].length)) .attr("width", d => xScale(d.avg_interval)) .attr("height", yScale.bandwidth() / d[1].length - 2) .attr("fill", d => colorScale(d.opcode)); // 5. 添加坐标轴 svg.append("g") .call(d3.axisLeft(yScale)) .selectAll("text") .attr("class", "axis-label"); svg.append("g") .attr("transform", `translate(0,${height})`) .call(d3.axisBottom(xScale)); // 6. 添加图例 const legend = svg.append("g") .attr("transform", `translate(${width + 20}, 20)`); colorScale.domain().forEach((opcode, i) => { legend.append("rect") .attr("y", i * 25) .attr("width", 18) .attr("height", 18) .attr("fill", colorScale(opcode)); legend.append("text") .attr("x", 25) .attr("y", i * 25 + 14) .text(opcode); }); </script> </body> </html> ``` **D3.js优势**: - **交互性强**:支持悬停高亮、点击筛选 - **动态更新**:可实时响应数据变化 - **高度定制**:自由控制所有视觉元素 - **响应式设计**:自动适应屏幕尺寸 --- ### 方案对比 | **特性** | Python (Seaborn) | D3.js | |------------------|------------------------|-----------------------| | 开发速度 | ★★★★★ (快速) | ★★★☆☆ (需前端知识) | | 交互性 | ★★☆☆☆ (静态) | ★★★★★ (丰富交互) | | 定制灵活性 | ★★★☆☆ | ★★★★★ | | 部署复杂度 | 简单 (本地图片导出) | 需Web服务器 | | 大数据支持 | ★★★★☆ | ★★★☆☆ (性能依赖) | --- ### 数据处理建议 如果原始JSON结构复杂,建议先预处理: ```python # 复杂JSON转换示例 import json with open('data.json') as f: raw = json.load(f) processed = [] for entry in raw: for op in entry["operations"]: processed.append({ "oid": entry["object_id"], "opcode": op["type"], "avg_interval": op["stats"]["avg_interval"] }) df = pd.DataFrame(processed) ``` --- ### 相关问题 1. 如何优化Seaborn分组条形图的标签重叠问题? 2. 在D3.js中如何实现条形图的动态排序功能? 3. 当数据量极大时(>10,000条),应该选择哪种可视化方案? 4. 如何将Python生成的图表嵌入到Web页面中? 5. 有哪些方法可以增强D3.js图表的可访问性? [^1]: 基础图表实现参考Matplotlib官方文档 [^2]: D3.js分组条形图设计模式参考《Interactive Data Visualization for the Web》 [^3]: Seaborn高级分组技巧见Seaborn Gallery示例 [^4]: 大数据优化策略详见IEEE VisComm 2022最佳实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值