算法每日一刷

LeetCode算法题-6. Z 字形变换(Swift)

2019-09-20  本文已影响0人  entre_los_dos

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zigzag-conversion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目

将一个给定字符串根据给定的行数,以从上往下、从左到右进行 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"
解释:

L     D     R
E   O E   I I
E C   I H   N
T     S     G

由规律可得:第行第一个和第二个差2(numRows-line) 或者 2(line - 1)。以示例2为例。
第一行:L和D。2 *(4-1)= 6。L是第1位,D是第7位。差6个。
第二行:E和O。2 (4-2)= 4。E是第2位,O是第6位。差4个。(从T-O)
O和E。2
(2-1)= 2。O是第6位。E是第8位。差2个。(从O-E)
...
第numRows行:和第一行一样。是个例外。

方法

func convert(_ s: String, _ numRows: Int) -> String {
        
        if numRows == 1 {
            return s
        }
        var result:String = ""
        
        for line in 1...numRows {
            
            var currentIndex = line
            var isFromBottom = true
            
            while currentIndex <= s.count {
                
                result.append(s[s.index(s.startIndex, offsetBy: currentIndex-1)])
                
                if line == numRows || line == 1{
                    currentIndex += 2 * (numRows - 1)
                }else {
                    if isFromBottom {
                        currentIndex += 2 * (numRows - line)
                    }else {
                        currentIndex += 2 * (line - 1)
                    }
                    isFromBottom = !isFromBottom
                }
            }
            
            
        }
        return result
    }

方法2-速度更快。

func convert(_ s: String, _ numRows: Int) -> String {
        guard numRows > 1 else { return s }
        var curRow = 0
        var arr = Array(s)
        var result = ""
        
        for row in 0..<numRows {
            var i = 0
            var index = i * (2 * numRows - 2) + row
            
            while index < arr.count {
                result.append(arr[index])
                i += 1
                let prevIndex = index
                index = i * (2 * numRows - 2) + row
                let nextIndex = i * (2 * numRows - 2) - row

                if nextIndex < arr.count, nextIndex != index, nextIndex != prevIndex {
                    result.append(arr[nextIndex])
                }
            }
        }
        
        return result
    }
上一篇 下一篇

猜你喜欢

热点阅读