ARTS打卡第五週

Algorithm:Leetcode 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"

解釋:

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

思路一:
拿到題目的首先思路就是用一個二維矩陣來存儲Z字形變換的結果。用二維矩陣需要知道三個要素:行數、列數和每個字母在矩陣中的位置。行數是輸入的,列數需要根據字符串的長度來計算,通過移動行和列的索引來確定字母在矩陣中的位置。

public String convert(String s, int numRows) {
        if(numRows == 0) {
            return null;
        }
        if(numRows == 1) {
            return s;
        }

        // 計算列數
        int tempLen = 0;
        int numCols=0;
        while(tempLen < s.length()) {
            if(numCols % (numRows-1) == 0) {
                tempLen += numRows;
            } else {
                tempLen += 1;
            }
            numCols++;
        }

        char[][] ans = new char[numRows][numCols];
        boolean down = false;
        int row=0;
        int col=0;
        // 遍歷字符串
        for(int j=0; j<s.length(); j++) {
            System.out.println("row:"+ row + " col:" + col);
            ans[row][col] = s.charAt(j);
            // 改變方向
            if(row == 0 || row == numRows-1) {
                down = !down;
            }
            if(down) {
                row++;
            } else {
                row--;
                col++;
            }
        }

        StringBuilder sb = new StringBuilder();
        for(row=0; row<numRows; row++) {
            for(col=0; col<numCols; col++) {
                if(ans[row][col] != 0) {
                    sb.append(ans[row][col]);
                }
            }
        }
        return sb.toString();
    }

時間複雜度:遍歷字符串是O(n),遍歷二維數組是O(numRows*numCols) > O(n)。

思路二:
由於思路一中二維矩陣存儲中有很多單元是無用的,輸出結果前還需要將其過濾掉,增加了時間複雜度。我們可以將二維矩陣中的無效單元壓縮掉。雖然結果看上去是Z字形,但實際我們不需要按Z字形輸出,所以沒必要按Z字形存儲,可以將列存儲得更緊湊些。

public String convert(String s, int numRows) {
        if(numRows == 0) {
            return null;
        }
        if(numRows == 1) {
            return s;
        }
        numRows = Math.min(s.length(), numRows);
        StringBuilder[] ans = new StringBuilder[numRows];
        for(int i=0; i<numRows; i++) {
            ans[i] = new StringBuilder();
        }

        boolean down = false;
        int row=0;
        // 遍歷字符串
        for(int j=0; j<s.length(); j++) {
            // 改變方向
            if(row == 0 || row == numRows-1) {
                down = !down;
            }
            ans[row].append(s.charAt(j));
            row += down ? 1 : -1;
        }

        StringBuilder sb = new StringBuilder();
        for(row=0; row<numRows; row++) {
            sb.append(ans[row]);
        }
        return sb.toString();
    }

時間複雜度:需要遍歷一遍字符串,所以是O(n)
空間複雜度:需要2n個額外存儲空間,所以是O(n)

Review: The Huawei Ban — How the Trade War is Hurting Tech

美國對華爲的禁令會造成什麼影響?對華爲來說,硬件不是太大的問題,但是想替換掉Android系統,還是很難的。製作一個新的系統,對華爲來說不是不可能,事實上,華爲已經有了自己的操作系統。最大的挑戰是建立一個生態系統。
坦白地說,並沒有證據證明華爲的手機相比其他Android手機有更大的安全問題。這次禁令明顯就是美中之間貿易戰的結果。

Ultimately, we’re trading innovation and technological advancement for national pride, an economic tug-of-war, and intellectual property discrepancies.
最終,我們正在用創新和技術進步來換取民族自豪感、(贏得)經濟拔河(的勝利)和(彌補)知識產權的差異

儘管華爲在美國的市場份額不大,但仍然和美國企業形成了競爭關係。從技術角度來說,這種競爭促進了前沿技術的進步(面部識別、屏幕下指紋識別、彈出式相機和摺疊手機等)。如果沒有這種競爭關係,企業將不會再以如此快的頻率更新自己的產品,壟斷現象會加劇,科技進步將會停止。競爭是工業創新的關鍵驅動力。

With better technology, humanity blossoms
有了更好的技術,人類纔會繁榮

Under what conditions, then, should we be okay with sacrificing this development? How much do we value technology’s ability to improve the well-being of individuals and societies?
那麼,在什麼條件下,我麼可以犧牲這種發展呢?我們在多大程度上重視技術改善個人和社會福祉的能力呢? PS:有道翻譯的太好了!!!

If the blacklist is implemented at much larger scale, to what extent can such political actions obstruct the growth of tech and, in effect, the enhancement of quality of life?
如果黑名單被大規模實施,這種政治行爲會在多大程度上阻礙科技的發展,並在實質上阻礙生活質量的提高?

Keeping this question in mind when considering global affairs is imperative, since ultimately, we are the people who are affected.

Tip: Shell腳本中如何獲取當前目錄?

#!/bin/bash
cur_dir=$(dirname $0)
cd $cur_dir
dir_path=$(pwd)

說明:
$0 是Shell中的特殊變量,表示當前腳本的文件名
$(dirname $0) 獲取當前腳本所在的目錄,可能是絕對路徑,也可能是相對路徑
cd 命令進入腳本所在目錄
$(pwd) 獲取當前目錄的絕對路徑

上述腳本可以簡寫成

#!/bin/bash
dir_path=$(cd `dirname $0`; pwd)

附錄:Shell中的特殊變量

$$ 
Shell本身的PID(ProcessID) 
$! 
Shell最後運行的後臺Process的PID 
$? 
最後運行的命令的結束代碼(返回值) 
$- 
使用Set命令設定的Flag一覽 
$* 
所有參數列表。如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數。 
$@ 
所有參數列表。如"$@"用「"」括起來的情況、以"$1" "$2" … "$n" 的形式輸出所有參數。 
$# 
添加到Shell的參數個數 
$0 
Shell本身的文件名 
$1~$n 
添加到Shell的各參數值。$1是第1參數、$2是第2參數…。 

Share: 讀碩士和博士的短短几年真正學到的是什麼?

Intellectual Skills 智力

Communication Skills 溝通能力

Personality Characteristics 人格

Habits Of Work 工作習慣

Mechanical Skills 動手能力

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章