leetcode 6 Z 字形变换 c代码

题目如下:

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L   C   I   R
E T O E S I I G
E   D   H   N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"

刚看到这道题的时候,动手在纸上画了下,发现第一行字符出现的下标在原始字符串中是有规律的,ai = i(2 * row - 2),紧接着找下面的行,找了几分钟无果。本着先解决问题的态度,打算暴力解下,使用二维数组,遍历字符串,逐个字符读取到数组中,最后再从数组中读取出来。这个想法阔以,点提交的时候提示超出时间限制.......暴力无果,卒。

重新找规律,其实规律也不是那么难找,第一行和最后一行规律基本上都是i(2*row - 2),中间行的字符规律看似不好找,不是。

每个字符与下一个字符是对称的。例如题目中的第二行,前两个字符ET和第一行终点E对称,距离为n - i,n为总行数,i为第i行。

此外就是第一个数和第二数是对称的,第二个数和第三个数也是对称的,只不过对称的距离不同,稍稍总结下可得每行字符下标规律:

设行数为i,那么第i行第k个元素下标右下列式子可得:
当i为首行或者尾行时,Ak = (i - 1) + 2(row - 2);
当i为中间行时,A1 = i - 1;
              Ak = Ak-1 + (k%2 ? (row - i) : (i - 1));

知道了规律,就可以按行从原始字符串中读取字符了。

看了官方给的按行读取方法,顺序读取字符串,添加到行中,每读取一个字符,添加到一行中,同时指向下一行,当到了行尾或者行首则改变行的方向。方法是不错,不过如果用c语言实现的话,不是还得为每一行申请一块内存吗?这块内存大小又不能确定,这和数组法有啥区别。

下面是找规律的c代码:

char * convert(char * s, int numRows){
    int len = 0, row = 0, i = 0, j = 0, k = 0;
    char *pstr;
    pstr = s;
    
    if (!s || numRows < 2)
        return s;
    
    while (*pstr++ != '\0')len++;
    
    if (len < 2)
        return s;
    
    pstr = (char *)malloc(sizeof(char) * (len + 1));
    if (!pstr)
        return NULL;
    
    i = 0;
    for (row = 1; row <= numRows; row++)
    {
        //按行读取每个字符下标
        j = row - 1;
        if (row == 1 || row == numRows)
        {            
            while (j < len)
            {
                pstr[i++] = s[j];
                j += (2 * numRows - 2);
            }
        }
        else
        {
            k = 1;
            while(j < len)
            {
				pstr[i++] = s[j];
                j = j + ((k++ % 2) ? 2 * (numRows - row) : 2 * (row - 1));
            }
        }   
    }
    pstr[i] = '\0';
    return pstr;
} 

编码的时候挖了一个坑," ?: "三目运算符的优先级低于加号,导致运算有问题!!!

参考资料:

1. 数据结构 : C语言版/ 严蔚敏,吴伟民编著

=============================================================================================

Linux应用程序、内核、驱动开发交流讨论群(745510310),感兴趣的同学可以加群讨论、交流、资料查找等,前进的道路上,你不是一个人奥^_^。

好的,以下是LeetCode 635题用C语言实现的代码,希望能够帮到您。 题目描述: 设计一个简易日志系统,支持以下操作: 1. 新增一条日志到日志系统中。 2. 统计日志系统中某个给定时间段内的日志数量。 3. 统计日志系统中所有日志的数量。 实现: ```c typedef struct { char* id; int timestamp; } Log; typedef struct { Log* logs; int size; int capacity; } LogSystem; LogSystem* logSystemCreate() { LogSystem* obj = (LogSystem*)malloc(sizeof(LogSystem)); obj->logs = (Log*)malloc(sizeof(Log) * 1001); obj->size = 0; obj->capacity = 1001; return obj; } void logSystemAdd(LogSystem* obj, int id, char* timestamp) { obj->logs[obj->size].id = (char*)malloc(sizeof(char) * 15); sprintf(obj->logs[obj->size].id, "%d", id); char year[5], month[3], day[3], hour[3], minute[3], second[3]; strncpy(year, timestamp, 4); year[4] = '\0'; strncpy(month, timestamp + 5, 2); month[2] = '\0'; strncpy(day, timestamp + 8, 2); day[2] = '\0'; strncpy(hour, timestamp + 11, 2); hour[2] = '\0'; strncpy(minute, timestamp + 14, 2); minute[2] = '\0'; strncpy(second, timestamp + 17, 2); second[2] = '\0'; obj->logs[obj->size].timestamp = atoi(year) * 100000000 + atoi(month) * 1000000 + atoi(day) * 10000 + atoi(hour) * 100 + atoi(minute); obj->size++; } int* logSystemRetrieve(LogSystem* obj, char* s, char* e, char* gra, int* returnSize) { int start, end, len; int* res = (int*)malloc(sizeof(int) * obj->size); *returnSize = 0; if (strcmp(gra, "Year") == 0) { start = atoi(strncpy(s, s, 4)) * 1000000; end = atoi(strncpy(e, e, 4)) * 1000000; len = 4; } else if (strcmp(gra, "Month") == 0) { start = atoi(strncpy(s, s, 7)) * 10000; end = atoi(strncpy(e, e, 7)) * 10000; len = 7; } else if (strcmp(gra, "Day") == 0) { start = atoi(strncpy(s, s, 10)) * 100; end = atoi(strncpy(e, e, 10)) * 100; len = 10; } else if (strcmp(gra, "Hour") == 0) { start = atoi(strncpy(s, s, 13)); end = atoi(strncpy(e, e, 13)); len = 13; } else if (strcmp(gra, "Minute") == 0) { start = atoi(strncpy(s, s, 16)); end = atoi(strncpy(e, e, 16)); len = 16; } else { start = atoi(strncpy(s, s, 19)); end = atoi(strncpy(e, e, 19)); len = 19; } for (int i = 0; i < obj->size; i++) { int time = obj->logs[i].timestamp; if (time >= start && time < end) { res[(*returnSize)++] = atoi(obj->logs[i].id); } } int* result = (int*)malloc(sizeof(int) * (*returnSize)); for (int i = 0; i < *returnSize; i++) { result[i] = res[i]; } free(res); return result; } void logSystemFree(LogSystem* obj) { for (int i = 0; i < obj->size; i++) { free(obj->logs[i].id); } free(obj->logs); free(obj); } ``` 这段代码实现了一个简单的日志系统,包含了新增日志、统计日志数量等操作。在这个实现中,我们使用了结构体Log和LogSystem来表示日志和日志系统。其中,Log包含了日志的id和时间戳,LogSystem包含了日志数组、数组大小和数组容量。 在新增日志的操作中,我们将日志的id和时间戳存储到日志对象中,同时将日志对象存储到日志数组中。 在统计日志数量的操作中,我们首先根据粒度参数gra将起始时间s和结束时间e转换成整数形式,然后遍历日志数组,统计符合要求的日志数量。 最后,在释放日志系统对象的操作中,我们需要将每个日志对象中的id字符串释放掉,并释放日志数组和日志系统对象本身所占用的内存。 希望这段代码能够帮到您,如果您有任何问题或疑问,请随时向我提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值