LeetCode - 6 - ZigZag Conversion
阿新 • • 發佈:2017-07-12
時間 pen src bind 數量 中間 lee zigzag []
題目
URL:https://leetcode.com/problems/zigzag-conversion
解法
一、程序員
對於一個程序員來說,肯定是想模擬 ZigZag 的數組,再根據 ZigZag 的位置一行一行的輸出。
ZigZag 模擬很簡單,首先得出行數和列數,之後模擬 ZigZag 方式:先向下,後對角,都是遇到邊界停下。
public String convert(String s, int numRows) { if (numRows == 1) return s; int step = 2 * numRows - 2;int columnRows = (s.length() / step + 1) * (step / 2); char[][] c = new char[numRows][columnRows]; int count = 0, i = 0, j = 0; boolean isDown = true; while (count < s.length()) { c[i][j] = s.charAt(count); count++; if (i == numRows - 1) { isDown= false; } else if (i == 0) { isDown = true; } if (isDown) { i++; } else { i--; j++; } } StringBuilder result = new StringBuilder(); for (int row = 0; row < c.length; row++) {for (int col = 0; col < c[0].length; col++) { if (c[row][col] != ‘\u0000‘) result.append(c[row][col]); } } return result.toString(); }
程序員,時間復雜度O(n2),運行時間約為 90 ms。
二、數學家
必然有規律可以輸出。
首先觀察分組,每組數量是 2 * numRows - 2,對應的是一個縱列和對角列(當然不包括下一個縱列的頭)。
其次觀察分對,在分組中可以發現,第一個元素沒有配對;第二個元素和倒數第一個元素配對;第三個元素和倒數第二個元素配對;······;中間有個元素,即 numRows -1 行的元素,是沒有配對的,直接輸出。
上面的思想完成之後,就可以具體實現:
- 輸出第一列;
- 確定每個分組中每個分對的起始下標,輸出分對元素;
- 輸出最後一列。
public String convert(String s, int numRows) { if (numRows == 1) return s; int step = 2 * numRows - 2; StringBuilder result = new StringBuilder(); for (int i = 0; i < s.length(); i += step) { result.append(s.charAt(i)); } for (int line = 1; line < numRows - 1; line++) { for (int i = line; i < s.length(); i = i + step) { result.append(s.charAt(i)); if (i + (numRows - line - 1) * 2 < s.length()) { result.append(s.charAt(i + (numRows - line - 1) * 2)); } } } for (int i = numRows - 1; i < s.length(); i += step) { result.append(s.charAt(i)); } return result.toString(); }
數學家,時間復雜度O(n2),運行時間約為 40 ms。
總結
程序員會數學真的是要上天。程序員應該學好數學,數學是計算機的基礎。利用數學相關知識,可以優化程序性能。
LeetCode - 6 - ZigZag Conversion