刷题的日常

1 篇文章 0 订阅
1 篇文章 0 订阅

MySQL题目:

如果熟悉case end流程函数的话,这道题还是不难的。我做这道题的时候,首先想如何解决新字段名该怎么设置,回忆以往做的习题和经验,我就联想到case end流程函数。紧接着我先敲一些代码看看结果输出如何。代码如下图所示:

select id ,   
(case when month = "Jan" then revenue end) 'Jan_Revenue',
(case when month = "Feb" then revenue end) 'Feb_Revenue',
(case when month = "Mar" then revenue end) 'Mar_Revenue'
from Department
group by id;

结果运行:

这是我中间解题过程中的卡住的点,在想着如何将下面id为1的两条数据整合到第一条数据呢?后来思索了一会终于想到了聚合函数sum(),max()。这两种聚合都是可以将数据整合在一起的。以下是别人更为详细的解释。

最后总的代码如下:

select id ,   
sum(case when month = "Jan" then revenue end) 'Jan_Revenue',
sum(case when month = "Feb" then revenue end) 'Feb_Revenue',
sum(case when month = "Mar" then revenue end) 'Mar_Revenue',
sum(case when month = "Apr" then revenue end) 'Apr_Revenue',
sum(case when month = "May" then revenue end) 'May_Revenue',
sum(case when month = "Jun" then revenue end) 'Jun_Revenue',
sum(case when month = "Jul" then revenue end) 'Jul_Revenue',
sum(case when month = "Aug" then revenue end) 'Aug_Revenue',
sum(case when month = "Sep" then revenue end) 'Sep_Revenue',
sum(case when month = "Oct" then revenue end) 'Oct_Revenue',
sum(case when month = "Nov" then revenue end) 'Nov_Revenue',
sum(case when month = "Dec" then revenue end) 'Dec_Revenue'
from Department
group by id;

运行结果如下:

总结:

1、新的字段设计其实可以用case end流程函数也可以用ifnull(),if()等这些来设置,不过具体情况具体分析。

2、如果将几条数据整合在一起,可以用聚合函数。聚合函数并不是那种把所有数据累加那么简单单一的功能,也能整合多条数据。

Java题目:

大二那时候的我也做过这道题,当时单纯的我只会认为“万物皆可暴力”,没有考虑时间复杂度这些,哈哈哈哈哈哈。如果再看这篇文章的您也是这种想法,答应我,咱们多用用别的方法。把BF算法改成KMP算法也好。如果您对这个不熟悉,可以在B站搜索青岛大学王卓老师的数据结构视频,KMP算法在字符串那部分,可自行查看,她讲数据结构还是比较不错的,至少比我的大学老师讲的好太多倍了(小小吐槽一下)。对于KMP算法,可以自行了解哟,毕竟还是有些需要理解的。

王卓老师讲解KMP算法      icon-default.png?t=O83Ahttps://www.bilibili.com/video/BV1nJ411V7bd?p=67&vd_source=0c35f70dcef0a3e5043b0c7a794c3f5a快速理解KMP算法icon-default.png?t=O83Ahttps://www.bilibili.com/video/BV1AY4y157yL/?spm_id_from=333.337.search-card.all.click

如果您看完视频,大概对KMP算法有更深的了解。其实KMP算法主要是计算出搜索字符串的next[]数组。根据next数组我们可以不用讲匹配失败的源字符串和搜索字符串重新拉回,从而将时间复杂度O(m*n)优化成O(m+n)。对于next数组的求法,以及源字符串和搜索字符串的匹配等视频连接有更详细的讲解。最后的代码如下所示:

class Solution {
    public int strStr(String haystack, String needle) {
        int[] next =new int[needle.length()];
        int prefix_len=0;
        next[0]=0;
        int i=1;
        while (i<needle.length()){
            if(needle.charAt(i)==needle.charAt(prefix_len)){
                prefix_len+=1;
                next[i]=prefix_len;
                i+=1;
            }else {
                if (prefix_len==0){
                    next[i]=0;
                    i+=1;
                }else{
                    prefix_len=next[prefix_len-1];
                }
            }
        }
        i=0;
        int j=0;
        while (i<haystack.length()){
            if (haystack.charAt(i)==needle.charAt(j)){
                i++;
                j++;
            }else if (j>0){
                j=next[j-1];
            }else {
                i+=1;
            }

            if (j==needle.length()){
                return i-j;
            }
        }
        return -1;
    }
}

代码虽然不比BF算法的代码少,但是我们确实让时间复杂度更加优化。直到我看到别人的代码时候,确实让我感觉好心累呀!

class Solution {
    public int strStr(String haystack, String needle) {
       return haystack.indexOf(needle);
    }
}

看到别人的代码,我的心里只有......,OK fine。果然能躺着就不要站着。后来我去看了indexOf的底层代码,让我更加佩服别人对代码的理解和深度。底层代码如下图所示:

static int indexOf(char[] source, int sourceOffset, int sourceCount,
            char[] target, int targetOffset, int targetCount,
            int fromIndex) {
        if (fromIndex >= sourceCount) {
            return (targetCount == 0 ? sourceCount : -1);
        }
        if (fromIndex < 0) {
            fromIndex = 0;
        }
        if (targetCount == 0) {
            return fromIndex;
        }

        char first = target[targetOffset];
        int max = sourceOffset + (sourceCount - targetCount);

        for (int i = sourceOffset + fromIndex; i <= max; i++) {
            /* Look for first character. */
            if (source[i] != first) {
                while (++i <= max && source[i] != first);
            }

            /* Found first character, now look at the rest of v2 */
            if (i <= max) {
                int j = i + 1;
                int end = j + targetCount - 1;
                for (int k = targetOffset + 1; j < end && source[j]
                        == target[k]; j++, k++);

                if (j == end) {
                    /* Found whole string. */
                    return i - sourceOffset;
                }
            }
        }
        return -1;
    }

底层代码写的更加丝滑和全面,对于起始索引比源字符串更大和搜索字符串为0的情况进行了判断,而且代码中没有next[]数组,并且对max匹配次数变量计算,以减少无用匹配次数从而提高匹配效率。

这两段截取代码让我对for循环和while循环等控制结构有了新的认知,既能判断又能循环,并且这些循环结构没有复杂多余的代码体。果然大神就大神,写的相当丝滑,这些优秀的代码需要不断的回味。总的来说还得继续加油努力呀。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值