LetCode387题详细分析附求解代码


题干分析:

    根据题干中给出的信息,题目中要求为找出所给字符串中的独一无二的元素,且给出最先出现的该类元素的对应角标。如果该字符串中没有独一无二的元素就返回-1.

解题分析:

    ​因为考虑到要进行字符串中字符的比较,所以想到了昨天该推送的将String转为char[] 的toVCharArray()的方法。有了字符串数组就可以进行每个字符之间的比较了,而题目中要求找出整个字符串中只出现了一次的元素,所以应该有个可以将每一位元素与整个字符串数组进行比较的方法,我们这里用到了两个for循环,第一个循环用来将每一位字符拿出来进行比较,第二个循环用来将拿出来的字符与整个字符串数组进行比较。通过当发现该位在整个字符串数组中有其他的相同的元素就进行标记的方法来知道该位不是我们要找的元素,如果该位遍历完整个字符串数组都没有相同的元素的话就相当于找出了这种独一无二的元素,如果遍历完整个数组都没有找到这种独一无二的元素就输出-1.

问题解决:

public class Solution {

    public int firstUniqChar(String s) {

             ​    ​char[]ch=s.toCharArray();

           char[] ch1=new char[s.length()];

           for(int i=0;i<s.length();i++){

                 for(int j=0;j<s.length();j++){

                      if(ch[i]==ch[j])

                            ch1[i]+=1;

                      if(j<s.length()&ch1[i]>1)

                            j=s.length();

                      if(j==s.length()-1&ch1[i]==1)

                                  returni;

                 }

           }   

           return -1;

    }

}

本题总结:

    ​在做本题的过程中遇到了以下几个问题来和大家分享:

    ​1.首先是题目理解错了,本来理解为比较一个字符串s和给定的leetcode字符串来进行比较,找出那个字符串s和给定字符串的不一样字符出现的位置,当时就很纳闷如果要将这两个字符串进行比较的话,但是题目中只限定了要比较的字符串为s,那么另外一个字符串要用什么符号来进行比较才会和leetcode自带的判断对错的符号相同呢,难道要用public static final来定义字符串?!!

    ​2.遇到的第二个问题是正确理解了题目之后,将每一位的字符进行与整个字符串数组进行遍历,记下每个字符在这个字符串中所出现的次数,然后进行找出第一次出现的且次数为1的即可,提交之后,答案是对的,可是时间超出了。所以进行了改进。

第一次改进为当所在位的字符与整个字符串数组比较完之后,如果其次数还是1的话就进行输出,这样的好处有两点:(1)可以不用对整个字符串数组的每一位都进行次数的统计,这样能极大的提高代码运行出结果的效率;(2)可以在该独一无二的元素第一次出现就能立马将其输出,因为题目中只要求找出第一次出现的该元素,而不用找出所有的该种元素,所有后面的字符串有没有该种元素是不用考虑的。不用找出整个字符串数组中每一位字符的次数然后再找出第一次出现的独一无二元素进行输出,也能提高代码的效率。利用该种思想就有了代码if(j==s.length()-1&ch1[i]==1) return i;可是添加该行代码提交之后还是会出现超时的情况,仔细看了之后才发现原来题目测试了一个非常长的字符串,所以就进行了第二次的改进。

第二次的改进为考虑到如果有一个非常长的字符串,如果一个字符在字符串中出现了很多次的话就不用真实的记录它在该字符串中出现的次数,我们只需要当知道该位的字符串不是我们想找的字符,就可以马上进行验证下一个字符,所有这时当进行判断该位所统计的次数已经>1的话就直接让该位跳出与整个字符串进行比较的循环,这样对于非常长的字符串数组进行比较的话也能极大的提高代码效率。实现该功能的代码为if(ch1[i]>1&&j<s.length()) j=s.length();该代码对终打败了8.49%的对手。

通过这两个代码的改进从中学到了以下几点:

1.对于已经发现不满足要求的元素就可以马上进行比较下一个元素,不要浪费时间知道其到底不满足要求到什么程度。这种思想虽然不够严谨,但是对于问题的解决非常高效,其实对于现实中的事情亦是如此。

2.通过这道题目进一步验证了进行一些判断语句能够节省for语句所消耗的大量时间,从而通过优化代码来打败更多的人。

好的,以下是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、付费专栏及课程。

余额充值