算法題解-字符串+數(shù)組-CCI

一共三道題,兩道數(shù)組+上次剩下的一道字符串。其中1、3題,有一定的難度,需要思考。

像素翻轉(zhuǎn)

題目描述
有一副由NxN矩陣表示的圖像,這里每個像素用一個int表示,請編寫一個算法,在不占用額外內(nèi)存空間的情況下(即不使用緩存矩陣),將圖像順時針旋轉(zhuǎn)90度。
給定一個NxN的矩陣,和矩陣的階數(shù)N,請返回旋轉(zhuǎn)后的NxN矩陣,保證N小于等于500,圖像元素小于等于256。
測試樣例:
[[1,2,3],[4,5,6],[7,8,9]],3
返回:[[7,4,1],[8,5,2],[9,6,3]]
思路:
這題有兩種思路,難點還是在于不使用輔助空間。最容易想到的就是按層處理,每一層按照左->上,下->左,右->下,上->右的次序依次交換該行或列中的每一個元素,其中用臨時變量保存第一個用來替換的元素。時間復(fù)雜度是O(n^2)
第二個思路就很巧妙,先將第i行和第n-i-1行交換,然后經(jīng)過主對角線對稱交換。但是復(fù)雜度相近。

class Transform {
public:
    vector<vector<int> > transformImage(vector<vector<int> > mat, int n) {
        // write code here
        /*
        分圈考慮,從最外圈開始
        按照左->上,下->左,右->下,上->右的次序依次交換元素
        一直到最內(nèi)層
        */
        for(int i=0; i<n/2; i++) { //正在處理第幾層
            for(int j=i; j<n-1-i; j++) { //第i圈有n-i個元素
                int tmp = mat[i][j];
                mat[i][j] = mat[n-j-1][i];//左->上
                mat[n-j-1][i] = mat[n-i-1][n-j-1];//下->左
                mat[n-i-1][n-j-1] = mat[j][n-i-1];//右->下
                mat[j][n-i-1] = tmp;//上->右
            }
        }
        return mat;
    }
};

清除行列

題目描述
請編寫一個算法,若N階方陣中某個元素為0,則將其所在的行與列清零。
給定一個N階方陣int[]mat和矩陣的階數(shù)n,請返回完成操作后的int[][]方陣(C++中為vector<vector><int>>),保證n小于等于300,矩陣中的元素為int范圍內(nèi)。</int></vector></int></vector>
測試樣例:
[[1,2,3],[0,1,2],[0,0,1]]
返回:[[0,0,3],[0,0,0],[0,0,0]]
思路:
這題不難,坑在于不能遇到0就直接置0,不然后面處理同行列元素后都是0。要先標記,遍歷完全部的元素后置0。

class Clearer {
public:
    vector<vector<int> > clearZero(vector<vector<int> > mat, int n) {
        // write code here
        vector<bool> col(n, false);
        vector<bool> raw(n, false);
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(mat[i][j] == 0) {
                    col[i] = true;
                    raw[j] = true;
                }
            }
        }
        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                if(col[i] || raw[j])
                    mat[i][j] = 0;
            }
        }
                
        return mat;
    }
};

翻轉(zhuǎn)子串

題目描述
假定我們都知道非常高效的算法來檢查一個單詞是否為其他字符串的子串。請將這個算法編寫成一個函數(shù),給定兩個字符串s1和s2,請編寫代碼檢查s2是否為s1旋轉(zhuǎn)而成,要求只能調(diào)用一次檢查子串的函數(shù)。
給定兩個字符串s1,s2,請返回bool值代表s2是否由s1旋轉(zhuǎn)而成。字符串中字符為英文字母和空格,區(qū)分大小寫,字符串長度小于等于1000。
測試樣例:
"Hello world","worldhello "
返回:false

"waterbottle","erbottlewat"
返回:true
思路:
這題表述的其實不太清楚,一開始沒理解。其實表達的意思就是截取字符串放到字符串的結(jié)尾,截取的部分字符順序不變。例如原字符串是ABCD,截取A部分放到BCD之后變成BCDA。判斷是不是和原字符串的各部分相同就行了。
PS:是我見識太少了,旋轉(zhuǎn)的意思就是循環(huán)左移。
思路很巧妙,把ABCD和自己拼接起來變成ABCDABCD,如果符合題意,那么“旋轉(zhuǎn)”后的字符串一定是ABCDABCD的一個字串,這樣一來,就變成了常見的尋找字串問題??梢灾苯佑肧TL庫中的find()方法。當然,自己寫的話就要復(fù)現(xiàn)KMP算法了。

class ReverseEqual {
public:
    bool checkReverseEqual(string s1, string s2) {
        // write code here
        s1 = s1 + s1;
        if(s1.find(s2) != s1.npos)
            return true;
        else 
            return false; 
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容