1. 程式人生 > >LeetCode-Algorithms #006 ZigZag Conversion, Database #180 Employees Earning More Than Their Managers

LeetCode-Algorithms #006 ZigZag Conversion, Database #180 Employees Earning More Than Their Managers

from arr 結果 toc strong 遍歷 har ++ 以及

LeetCode-Algorithms #006 ZigZag Conversion

技術分享圖片

技術分享圖片

給定一個字符串, 以及需要輸出的行數, 將字符串按照給定行數進行Z字形排列(效果見上圖), 然後將得到的結果逐行拼接成一個新的字符串, 返回這個新串

我的思路:

通過給定的行數計算每一個字符在Z形排列中位於哪一行並不困難, 如果要求是排列為n行, 那麽原字符串中的字符所在的行數每前進2n-2個就會經歷一個循環

不難發現, 原字符串中的第i個字符只要滿足如下條件, 就必然在Z形排列的第n行出現:

i % (2 * numRows - 2) == n || i % (2 * numRows - 2) == (2 * numRows - 2 - n)

這樣, 遍歷後就可以得到各行的子串, 拼接後即可得到結果:

 1 class Solution {
 2     public String convert(String s, int numRows) {
 3         //排除特殊情況
 4         if(numRows == 1) return s;
 5         //建立一個字符串存儲結果
 6         String result = "";
 7         //把字符串轉化為字符數組
 8         char[] arr = s.toCharArray();
 9         //獲取字符串長度
10
int len = arr.length; 11 12 //分別獲取每一行中的字符 13 for (int n = 0; n < numRows; n++) { 14 //創建一個空串存儲每一行中的字符 15 String temp = ""; 16 //遍歷字符串數組, 把符合條件的字符存儲至temp中 17 for (int i = 0; i < len; i++) { 18 if (i % (2 * numRows - 2) == n || i % (2 * numRows - 2) == (2 * numRows - 2 - n)) {
19 temp = temp + arr[i]; 20 } 21 } 22 //把temp添加到result中 23 result = result + temp; 24 } 25 //返回結果 26 return result; 27 } 28 }

這樣處理雖然非常直觀, 但是效率很低, n行的結果就需要對字符串進行n次遍歷, 顯然是很低效的

參考提示後對代碼進行修改:

 1 class Solution {
 2     public String convert(String s, int numRows) {
 3         //排除特殊情況
 4         if(numRows == 1) return s;
 5         //把字符串轉化為字符數組
 6         char[] arr = s.toCharArray();
 7         //獲取字符串長度
 8         int len = arr.length;
 9         //排除特殊情況
10         if(len<=numRows)return s;
11         //建立一個字符串存儲結果
12         String result = "";
13         //建立一個StringBuilder的List存儲各行結果
14         List<StringBuilder> list = new ArrayList<>();
15         for(int i = 0; i < numRows; i++) {
16             list.add(new StringBuilder());
17         }
18         
19         //將各個字符添加至應在的行
20         for(int index = 0; index < len; index++) {
21             int rowIndex = (index % (2*numRows -2)) < numRows ? (index % (2*numRows -2)) : (2*numRows -2)-(index % (2*numRows -2));
22             list.get(rowIndex).append(arr[index]);
23         }
24         //組合結果
25         for (StringBuilder stringBuilder : list) {
26             result += stringBuilder.toString();
27         }
28         //返回結果
29         return result;
30     }
31 }

這樣顯然節省了不少計算, 但是實際上並沒有快很多, 主要問題我想還是出在細節上, 比如能用StringBuilder.append的地方用了字符串拼接等等

看一看官方答案, 就漂亮多了:

 1 class Solution {
 2     public String convert(String s, int numRows) {
 3 
 4         if (numRows == 1) return s;
 5 
 6         List<StringBuilder> rows = new ArrayList<>();
 7         for (int i = 0; i < Math.min(numRows, s.length()); i++)
 8             rows.add(new StringBuilder());
 9 
10         int curRow = 0;
11         boolean goingDown = false;
12 
13         for (char c : s.toCharArray()) {
14             rows.get(curRow).append(c);
15             if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
16             curRow += goingDown ? 1 : -1;
17         }
18 
19         StringBuilder ret = new StringBuilder();
20         for (StringBuilder row : rows) ret.append(row);
21         return ret.toString();
22     }
23 }

用了一個指針來記錄遍歷到的字符應該在哪一行, 節省了不少計算

再來看另一種思路, 遍歷的過程和我最開始的方法近似, 但是每次不是每個字符都遍歷, 而是每添加一個字符就將指針後推一個循環:

 1 class Solution {
 2     public String convert(String s, int numRows) {
 3 
 4         if (numRows == 1) return s;
 5 
 6         StringBuilder ret = new StringBuilder();
 7         int n = s.length();
 8         int cycleLen = 2 * numRows - 2;
 9 
10         for (int i = 0; i < numRows; i++) {
11             for (int j = 0; j + i < n; j += cycleLen) {
12                 ret.append(s.charAt(j + i));
13                 if (i != 0 && i != numRows - 1 && j + cycleLen - i < n)
14                     ret.append(s.charAt(j + cycleLen - i));
15             }
16         }
17         return ret.toString();
18     }
19 }

LeetCode-#180 Employees Earning More Than Their Managers

技術分享圖片

在職員表中找到薪資比其經理還高的職員的名字

這幾天做過幾個數據庫的題目後終於有了點感覺, 也沒啥說的:

1 SELECT e1.Name AS Employee
2 FROM
3     Employee e1,
4     Employee e2
5 WHERE
6     e2.Id = e1.ManagerId
7     AND e1.Salary > e2.Salary
8 ;

或者也可以用join, 下面這是官方提供的答案之一:

1 SELECT
2      a.NAME AS Employee
3 FROM Employee AS a JOIN Employee AS b
4      ON a.ManagerId = b.Id
5      AND a.Salary > b.Salary
6 ;

據說用JOIN會比用WHERE快一些, 我也不太確定, 總之就聽他的好了, 以後考慮多用JOIN

LeetCode-Algorithms #006 ZigZag Conversion, Database #180 Employees Earning More Than Their Managers