zoukankan      html  css  js  c++  java
  • 题目:Z字形变换

    第一次看到这道题,恍惚之间以为回到了儿童时期在做数学卷子。这tm就是个小学奥数题吧。

    然后面对这个小学奥数题,我花费了一个下午(顺路刷完了毒奶粉账号的疲劳);

    虽然花费的时间比较多但是提交之后发现又是一个超过百分之百的,感觉心情还不错。

    代码如下:

    static const auto io_speed_up = []()
    {
        std::ios::sync_with_stdio(false);
        cin.tie(nullptr);
        return 0;
    }();
    
    class Solution {
    public:
        string convert(string s, int numRows) {
            if (numRows == 1)
                return s;
            int length   = s.size();
            int groupNum = numRows + numRows - 2;
            bool isShort = false;
            if (groupNum > length)
            {
                s =  s + string(groupNum - length, '0');
                length  = groupNum;
                isShort = true;
            }
            int quotient  = length / groupNum;
            int remainder = length % groupNum;
            vector<int> num(groupNum);
            vector<int> sum(numRows);
            int i = 0;
            int j = 0;
            for (i = 0; i < remainder; ++i)
                num[i] = 1;
    
            sum[1] = quotient + num[0];
            for (int i = 2; i < numRows; ++i)
            {
                j = i - 1;
                sum[i] = sum[j] + quotient + quotient + num[j] + num[groupNum - j];
            }
    
            i = 0;
            j = 0;
            int group = 0;
            int doubleRow = numRows - 1;
            string res(s);
            while (group < quotient)
            {
                res[sum[0]++] = s[i++];
                j = 1;
                while(j < doubleRow)
                    res[sum[j++]++] = s[i++];
                res[sum[doubleRow]++] = s[i++];
                while(j > 1)
                    res[sum[--j]++] = s[i++];
                ++group;
            }
            j = 0;
            int k = 0;
            while(j < doubleRow && k++ < remainder)
                res[sum[j++]++] = s[i++];
            if (i < length)
            {
                res[sum[doubleRow]++] = s[i++];
                ++k;
            }
            while(j > 1 && k++ < remainder)
                res[sum[--j]++] = s[i++];
            if (isShort)
            {
                char* temp = new char[length];
                for (i = 0, j = 0; i < length; ++i)
                {
                    if(res[i] != '0')
                        temp[j++] = res[i];
                }
                temp[j] = '';
                res = string(temp);
            }
            return res;
        }
    };

    在这道题中,我把Z字型的一部分分为一组,即竖+斜等于一组,然后确定了两段每组会出现一个字符,然后中间的部分每组会出现两个字符。这里我们把输入为1的情况特殊处理,然后输入为2的情况,在代码中会跳过。接着因为这个方法处理字符最低为一组,所以我们碰到不足一组的在后面补‘0’补齐,然后把求出来的结果中‘0’字符去除。对于每一组,我们又可以分出两种情况,1是从上到下即N的竖线,2是从下到上即N的斜线,例如对于题目中所给的"PAYPALISHIRING",3这种情况我们可以分为

    P   A   H   N
    A P L S I I G
      Y   I   R  

    我把字符分为顶端,从上到下,底端,从下到上四种情况来处理,然后在处理完所有的组之后,我把不足一组的特殊处理。

    字符的处理我是开辟了一个行数大小的数组,然后记录每个数组的起始地方的字符下标,然后每处理好一个字符把该行要处理的字符下标+1;

    测完我的方法之后我去看了看之前排第一的方法,代码如下:

    static auto static_lambda = [] () {
        std::ios::sync_with_stdio(false);
        std::cin.tie(0);
        return 0;
    }();
    
    class Solution {
    public:
        string convert(string s, int numRows) {
            int length = s.length();
            if(length < numRows || numRows <= 1) return s;
            vector<string> r(numRows);
            int step = 1;
            int row = 0;
          
            for(int i = 0; i < length; i++)
            {
                if( row == numRows-1) step =-1;
                if(row == 0) step =1;
                
                r[row] += s[i];
                row += step;
            }
            
            string result;
            for (int i=0; i<numRows; i++)
                result += r[i];
            
             return result;
        }
    };

    他的代码很巧妙,把每一行设置成一个字符串,然后也是分组,每组两种情况。他设置碰到顶端,让下次累加字符串所在的数组是现在数组+1,如果碰到底端则是现在数组-1,到最后再把所有的字符串加起来。这种方法不需要考虑最后可能余下一部分不到一组的情况。

    我觉得这个代码每次字符串拼接浪费了时间,如果把他拼接的部分改为:计算好字符串大小然后分配数组,在数组范围内操作,最后分配一个答案大小的字符串再循环赋值,这样的话速度会比我的代码还要快,并且更容易理解。

  • 相关阅读:
    js简直了,连大小都不能直接比,还变量提升,这个是挖了多少坑啊,故意的把,,,,写起来又不简单,运行起来又不是很稳,很迷啊
    bootstrap 强制左移
    图片轮播/无缝滚动的原理
    jQuery放大镜的原理
    下拉列表的两种实现方式
    Html css图片文本对齐问题
    一键换肤原理
    setInterval与clearInterval用法
    jQuery课堂测验
    Css画圣诞树
  • 原文地址:https://www.cnblogs.com/change4587/p/9165184.html
Copyright © 2011-2022 走看看