Leetcode763. 划分字母区间(C语言)

本文介绍了一种使用贪心算法解决LeetCode 763题目的方法,该题要求将字符串划分为尽可能多的片段,使得每个字母只在一个片段中出现。通过记录每个字符的最远出现位置并以此更新片段范围,实现了高效求解。

Leetcode763. 划分字母区间(C语言)

算法-贪心思想:算法与数据结构参考

题目:

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。例:
输入: S = “ababcbacadefegdehijhklij”
输出: [9,7,8]

解释:
划分结果为 “ababcbaca”, “defegde”, “hijhklij”。每个字母最多出现在一个片段中。像 “ababcbacadefegde”, “hijhklij” 的划分是错误的,因为划分的片段数较少。

思路:
贪心算法。用map记录每个元素最后位置,以此为范围遍历,范围内有最后位置更靠后的(二次遍历)则更新范围。

参考力扣大佬

代码:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

void initmap(char *S, int map[26]){		//记录所有元素最后出现位置
    for (int i = 0; S[i]; ++i) {
        int k = S[i] - 'a';				//记录字符索引(0-25)
        if (i > map[k]) map[k] = i;		//之前遇到过的字符更新位置
    }
}

int* partitionLabels(char * S, int* returnSize){   
    if (!S)  return NULL;
    
    int  len  = strlen(S);
    int *result = (int *)malloc(sizeof(int) * len);
    int map[26] = {0};	initmap(S, map);
    *returnSize = 0;
    int pos = 0,start = 0,end = 0;  	//初始化,不能放在for内,否则每次改变
    
    for (int i = 0; i < len; ++i) {
        pos = map[S[i] - 'a']; 			//当前位置
        if (pos == end && i == end) {	//需要断开,开始下一个区间
            result[(*returnSize)++] = end - start + 1;	//记录当前区间元素个数
            end = i + 1;
            start = end;
        } 
        else if (pos > end)	 end = pos;	//区间范围内有更靠后的位置,更新范围
    }
    return result;
 }

### LeetCode 56 题目解析 LeetCode第56题要求解决区间合并的问题。给定一系列不重叠的区间,在这些区间中插入一个新的区间并进行合并,如果有必要的话[^1]。 ### 解决方案概述 为了有效地处理这个问题,可以先按照区间的起始位置对输入数组进行排序。接着遍历这个有序列表来判断当前区间是否与下一个区间有交集;如果有,则将这两个区间合并成一个更大的新区间继续比较下去直到完成整个过程[^2]。 ### C语言实现代码 下面是针对此问题的一个具体C语言解决方案: ```c #include <stdio.h> #include <stdlib.h> // 定义结构体表示区间 struct Interval { int start; int end; }; // 比较函数用于qsort()按start升序排列 int compare(const void* a, const void* b) { struct Interval *ia = (struct Interval *)a; struct Interval *ib = (struct Interval *)b; return ia->start - ib->start; } /** * Note: The returned array must be malloced, assume caller calls free(). */ struct Interval* merge(struct Interval* intervals, int intervalsSize, int* returnSize){ qsort(intervals, intervalsSize, sizeof(struct Interval), compare); // 动态分配内存存储结果 struct Interval *result = (struct Interval*)malloc(sizeof(struct Interval)*intervalsSize); *returnSize = 0; for (int i = 0; i < intervalsSize; ++i) { int L = intervals[i].start, R = intervals[i].end; if (!(*returnSize) || result[*returnSize-1].end < L) { result[(*returnSize)++] = intervals[i]; } else { result[*returnSize-1].end = fmax(result[*returnSize-1].end, R); } } return result; } ``` 该算法的时间复杂度主要取决于排序操作O(nlogn),其中n代表输入区间的数量。空间复杂度为O(1)(忽略返回的结果所占用的空间)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值