zoukankan      html  css  js  c++  java
  • 6-Z字形变换

    题目:

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

    比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:

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

    请你实现这个将字符串进行指定行数变换的函数:

    string convert(string s, int numRows);
    示例 1:

    输入: s = "LEETCODEISHIRING", numRows = 3
    输出: "LCIRETOESIIGEDHN"
    示例 2:

    输入: s = "LEETCODEISHIRING", numRows = 4
    输出: "LDREOEIIECIHNTSG"

    解答1:

    直接将string放到一个二维数组中,然后按照要求输出的顺序输出:

    string convert(string s, int numRows)
    {
        if (s.length() == 0 || numRows <= 1)    //如果是1行,直接返回
        {
            return s;
        }
    
        int length = s.length();
        char** array = new char*[numRows];
        for (int ii = 0; ii < numRows; ii++)
        {
            array[ii] = new char[length];
            for (int i = 0; i < length; i++)
            {
                array[ii][i] = 0;    //初始化
            }
        }
    
        int index = 0;
        int i=0, j = 0;//i表示行-numRows,j表示列-length
        while (index < length)
        {
            if (j % (numRows - 1) == 0)//表示竖列
            {
                if (i == numRows)
                {
                    j++;
                    i-=2;//i=numRows时,已经超过范围了,需要减2才符合要求
                }
                else
                {
                    array[i++][j] = s[index];
                    index++;
                    continue;
                }
            }
            else//正常情况的,i-- 然后j++
            {
                array[i--][j++] = s[index++];
            }
        }
    
        //输出
        string result = "";
        for (int j = 0; j < numRows; j++)//
        {
            for (int i = 0; i < length; i++)//
            {
                if (array[j][i] > 0)
                {
                    result+=array[j][i];
                }
            }
        }
    
        for (int ii = 0; ii < numRows; ii++)
        {
            delete[] array[ii];
        }
    
        return result;
    }

    结果:

      内存、运行时间都很差,时间复杂度为O(n^2),且创建了一个临时的二维数组,占用较多空间。

    解法2 按行排序:

    不用考虑字符串放置时的空格,将string中的字符放到各个行对应的容器中,然后拼接结果即可。

    思路

    通过从左向右迭代字符串,我们可以轻松地确定字符位于 Z 字形图案中的哪一行。

    算法

    我们可以使用 min(numRows,len(s)) 个列表来表示 Z 字形图案中的非空行。

    从左到右迭代 ss,将每个字符添加到合适的行。可以使用当前行和当前方向这两个变量对合适的行进行跟踪。

    只有当我们向上移动到最上面的行或向下移动到最下面的行时,当前方向才会发生改变。

    string convert(string s, int numRows)
    {
        if (numRows <= 1)
        {
            return s;
        }
    
        int row = min((int)s.size(), numRows);
        bool isGoingDown = false;
        int rowIdx = 0;
        vector<string> rowStrVec(row);
        for (int i = 0; i < s.size(); i++)
        {
            if (rowIdx == 0 || rowIdx == (row - 1))
            {
                isGoingDown = !isGoingDown;        //移动到第一行,最后一行时变换方向
            }
            
            rowStrVec[rowIdx] += s.at(i);
            rowIdx += (isGoingDown ? 1 : -1);    //如果到第一行,或者最后一行,改变方向
        }
    
        string result;
        for (auto str : rowStrVec)
        {
            result.append(str);
        }
        return result;
    }

    解法3 按行访问:

    找输入输出字符串中,特定位置的字符之间的关系,

     https://leetcode-cn.com/problems/zigzag-conversion/solution/z-zi-xing-bian-huan-by-leetcode/

  • 相关阅读:
    动态规划——Best Time to Buy and Sell Stock IV
    动态规划——Split Array Largest Sum
    动态规划——Burst Ballons
    动态规划——Best Time to Buy and Sell Stock III
    动态规划——Edit Distance
    动态规划——Longest Valid Parentheses
    动态规划——Valid Permutations for DI Sequence
    构建之法阅读笔记05
    构建之法阅读笔记04
    构建之法阅读笔记03
  • 原文地址:https://www.cnblogs.com/zyk1113/p/13793142.html
Copyright © 2011-2022 走看看