一个数字段由首尾两个数字标识,表示一个自然数集合,
比如数字段[beg, end)表示从beg到end之间的所有自然数,
包含beg,但不包含end。
有若干个数字段,这些数字段之间可能有重叠,
怎么把这些数字段合并去重,用最少个数的数字段来表示。
合并前后,整个集合包含的数字不发生变化。
第一行为数字N,表示接下来有N个数字段(N<=100000)
第二行开始一共有N行,每行两个数字,分别表示一个数字段的beg和end
(beg和end为无符号32位整数)
合并去重后形成的数字段集合,按升序排列。
4 3 8 3 7 4 6 7 9
3 9
import sys def InputFunc(): a = int(input()) data = [] for i in range(a): data.append(list(map(int, input().split()))) return a, data def main(): n, data = InputFunc() result = [] data = sorted(data) result.append(data[0]) for i in range(1, len(data)): if (data[i][0] > result[-1][1]): #不重叠 result.append(data[i]) else: result[-1][1] = max(result[-1][1], data[i][1]) for value in result: print(value[0], value[1]) if __name__ == "__main__": main()
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.Arrays; import java.util.ArrayList; class Node { public int start; public int end; public Node(int start, int end){ this.start = start; this.end = end; } } public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); Node[] nodes = new Node[n]; for(int i = 0; i < n; i++){ String[] params = br.readLine().split(" "); nodes[i] = new Node(Integer.parseInt(params[0]), Integer.parseInt(params[1])); } Arrays.sort(nodes, (a, b) -> a.start != b.start? a.start - b.start: a.end - b.end); ArrayList<Node> intervals = new ArrayList<>(); intervals.add(nodes[0]); // 合并区间 for(int i = 1; i < n; i++){ if(intervals.get(intervals.size() - 1).end >= nodes[i].start){ // 前后有区间重叠,进行区间合并,只需要将区间右端点改成大的那个就行 intervals.get(intervals.size() - 1).end = Math.max(intervals.get(intervals.size() - 1).end, nodes[i].end); }else{ // 没有区间重叠,直接加入 intervals.add(nodes[i]); } } for(Node node: intervals){ System.out.println(node.start + " " + node.end); } } }
有点暴力的解法
#include <iostream> using namespace std; int main() { bool x[1000000] = {0}; int N; cin >> N; int l, r; while(N--) { cin >> l >> r; for(int i = l; i < r; i++) { x[i] = 1; } } for(int i = 0; i < 1000000; i++) { if((i == 0 && x[i] == 1) || (x[i-1] == 0 && x[i] == 1)) { cout << i << " "; } else if(x[i-1] == 1 && x[i] == 0) { cout << i << endl; } } }
先把数据按照左值小的,右值大的排序,然后再遍历整个数组。如果两个值对(a,b),(c,d),如果a<=b &&b>=d那么对于(a,b)来说,(c,d)就可以被合并,如果b<d那么就可以把b的值替换为d,把(a,b)更新为 (a,d),如果c>b那么就意味着一个区间不能表示(a,b)和(c,d),必须要用两个区间来表示。遍历 一遍数组就行了。 import java.util.*; public class Main{ static class Pair implements Comparable<Pair>{ public int a; public int b; public Pair(int a,int b){ this.a=a; this.b=b; } @Override public int compareTo(Pair p){ if(a==p.a) return p.b-b; else return a-p.a; } } public static void main(String[] args){ Scanner sc=new Scanner(System.in); int n=sc.nextInt(); Pair[] ps=new Pair[n]; for(int i=0;i<n;i++){ int k=sc.nextInt(); int l=sc.nextInt(); ps[i]=new Pair(k,l); } Arrays.sort(ps); /*for(int i=0;i<n;i++){ System.out.println(ps[i].a+" "+ps[i].b); }*/ List<Pair> result=new ArrayList<>(); Pair now=ps[0]; for(int i=1;i<n;i++){ if(now.a<=ps[i].a&&now.b>=ps[i].b){ continue; }else if(ps[i].a>now.b){ result.add(now); now=ps[i]; } else now.b=ps[i].b; } result.add(now); for(Pair p:result){ System.out.println(p.a+" "+p.b); } sc.close(); } }
# coding=utf-8 import sys lines = [] try: while True: values = sys.stdin.readlines() values = [list(map(int, v.split())) for v in values] if not values: print break alls = [] for i in range(len(values)): for j in range(values[i][0], values[i][-1]): alls.append(j) res = list(set(alls)) duns = [] p1, p2 = 0, 0 while p2 <= len(res) - 1: if res[p2] - res[p1] == p2-p1: if p1 == len(res)-1: duns.append([res[p1], res[p1]+1]) if p1 != p2 and p2 == len(res) -1: duns.append([res[p1], res[p2]+1]) p2 += 1 else: duns.append([res[p1], res[p2-1]+1]) p1 = p2 for ans in duns: if len(ans)>1: print ans[0], ans[1] else: print ans[0] break except: pass
package main import ( "bufio" "os" "strings" "sort" "strconv" "fmt" ) func main() { inputReader := bufio.NewReader(os.Stdin) line0, _ := inputReader.ReadString('\n') line0 = strings.Replace(line0, "\n", "", -1) n, _ := strconv.Atoi(line0) nums := make([][2]int, n) for i := 0; i < n; i++ { line1, _ := inputReader.ReadString('\n') line1 = strings.Replace(line1, "\n", "", -1) lines1 := strings.Split(line1, " ") nums[i][0], _ = strconv.Atoi(lines1[0]) nums[i][1], _ = strconv.Atoi(lines1[1]) } sort.Slice(nums, func(i, j int) bool { return nums[i][0] < nums[j][0] }) res:=[][]int{} start:=nums[0][0] end:=nums[0][1] for i:=1;i<n;i++{ if nums[i][0]<=end{ end=max(end,nums[i][1]) }else{ res=append(res,[]int{start,end}) start=nums[i][0] end=nums[i][1] } } res=append(res,[]int{start,end}) for _,v:=range res{ fmt.Println(v[0],v[1]) } } func max(a, b int) int { if a > b { return a } return b }
#include<bits/stdc++.h> using namespace std; int d[100005]; int main() { int n; int left=99999; int right=0; cin>>n; memset(d,0,sizeof(d)); for(int i=0;i<n;i++){ int l,r; cin>>l>>r; if(l>r) swap(l,r); d[l+1]++; d[r+1]--; left=min(left,l+1); right=max(right,r+1); } for(int i=1;i<=right;i++){ d[i]+=d[i-1]; if(d[i]>0&&d[i-1]==0) cout<<i-1<<" "; else if(d[i]==0&&d[i-1]>0) cout<<i-1<<endl; } return 0; }差分,O(N)
process.stdin.resume(); process.stdin.setEncoding('ascii'); var input = ""; process.stdin.on('data', function (data) { input += data; }); process.stdin.on('end', function () { var input_array = input.split("\n"); //示例代码 var len = input_array.length; var result = []; var len1 = Number(input_array[0]) for(let i=1; i<len; i++){ let first = Number(input_array[i].split(' ')[0]) let second = Number(input_array[i].split(' ')[1]) for(let i=first;i<second;i++){ result.push(i) } } let newArr = Array.from(new Set(result)).sort((a, b) => a - b) let finalStr = `${newArr[0]}` for (let i = 1; i < newArr.length; i++) { if (newArr[i] != newArr[i - 1] + 1) { finalStr += (`${' ' + (newArr[i - 1] + 1)}\n${' ' + (newArr[i] + 1) - 1}`) } } console.log(`${finalStr} ${newArr[newArr.length - 1] + 1}`) return `${finalStr} ${newArr[newArr.length - 1] + 1}` })内存超了,我泪目了
#include<set> (855)#include<map> #include<iostream> (720)#include<algorithm> #include<vector> (721)#include<string> #include<queue> using namespace std; struct cmp { bool operator()(vector<int> &v1, vector<int>&v2) { return v1[0] > v2[0]; } }; vector < vector<int>> ff(priority_queue<vector<int>, vector<vector<int>>, cmp> &pq); int main() { priority_queue<vector<int>, vector<vector<int>>, cmp> less; int N = 0; cin >> N; int x = 0, y = 0; for (int i = 0; i < N; ++i) { cin >> x >> y; less.push({ x,y }); } vector < vector<int>> res = ff(less); for (auto &i : res) { for (auto j : i) cout << j << " "; cout << endl; } return 0; } vector < vector<int>> ff(priority_queue<vector<int>, vector<vector<int>>, cmp> &pq) { vector < vector<int>> res; auto t1 = pq.top(); pq.pop(); while (!pq.empty()) { auto tmp = pq.top(); pq.pop(); if (t1[1] >= tmp[0]) t1[1] = max({ t1[1],tmp[1] }); else { res.push_back(t1); t1 = tmp; } } res.push_back(t1); return res; }
import sys if __name__ == '__main__': N = int(sys.stdin.readline().strip()) raw_input = [] for line in sys.stdin: raw_input.append(list(map(int, line.split()))) raw_input.sort(key=lambda x:x[0]) res = [raw_input[0]] for value in raw_input: if value[0] <= res[-1][1]: res[-1][1] = max(res[-1][1], value[1]) else: res.append(value) for interval in res: print('{} {}'.format(interval[0], interval[1]))