1. 程式人生 > >leetcode題解-初級演算法陣列篇(6-11題)

leetcode題解-初級演算法陣列篇(6-11題)

繼續填坑,本篇文章帶來的是leetcode初級演算法陣列篇6-11題的題解。

第六題 兩個陣列的交集 II

題目描述:給定兩個陣列,編寫一個函式來計算它們的交集。

示例 1:

輸入: nums1 = [1,2,2,1], nums2 = [2,2]
輸出: [2,2]
示例 2:

輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
輸出: [4,9]
說明:輸出結果中每個元素出現的次數,應與元素在兩個陣列中出現的次數一致。我們可以不考慮輸出結果的順序

演算法說明:建立一個map索引,先遍歷nums1陣列,並把在map中儲存nums1陣列中每個元素的個數。然後遍歷nums2陣列,若該元素出現在map中的值大於0,則把該元素儲存到結果中,並且在map中把該值減1。這樣的話時間複雜度即掃描與查詢,複雜度為O(nlogn),如果用hash map可以優化只O(n)。

實現的程式碼如下:

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        map<int,int> table;
        vector<int> res;
        for(int i=0;i<nums1.size();i++)
            table[nums1[i]]++;
        for(int i=0;i<nums2.size();i++)
            if
(table[nums2[i]]>0) {res.push_back(nums2[i]);table[nums2[i]]--;} return res; } };

第七題 加一

題目描述:給定一個非負整陣列成的非空陣列,在該數的基礎上加一,返回一個新的陣列。最高位數字存放在陣列的首位, 陣列中每個元素只儲存一個數字。你可以假設除了整數 0 之外,這個整數不會以零開頭。
解題演算法:一開始看這個題目看錯了= =,wa了好多次,這題其實可以看成一個小加法模擬。解題思路就是給最後一位加一,然後判斷會不會進位,然後在最高位的時候也要判斷一次會不會在加一後等於10,如果是的話在陣列前方再新增一位1。只是簡單的模擬判斷,時間複雜度為O(n)。
實現的程式碼如下:

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int c;
        int temp;
        temp=digits[digits.size()-1];
        digits[digits.size()-1]=(digits[digits.size()-1]+1)%10;
        c=(temp+1)/10;
        for(int i=digits.size()-2;i>=0;i--){
        temp=digits[i];
        digits[i]=(digits[i]+c)%10;
        c=(temp+c)/10;
        }
        if(c==1){
            vector<int> res;
            res.push_back(1);
            for(int i=0;i<=digits.size()-1;i++)
                res.push_back(digits[i]);
            return res;
        }
        return digits;
    }
};

第八題 移動零

題目描述:給定一個數組 nums,編寫一個函式將所有 0 移動到陣列的末尾,同時保持非零元素的相對順序。
示例:
輸入: [0,1,0,3,12]
輸出: [1,3,12,0,0]
解題演算法:把不是0的數字放到前面,是0的最後加到陣列後面就行了,時間複雜度O(n)。
程式碼:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int j=0;
        for(int i=0;i<nums.size();i++)
            if(nums[i]!=0) nums[j++]=nums[i];
        for(int i=j;j<nums.size();j++)
            nums[j]=0;
    }
};

第九題 兩數之和

題目描述:給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。示例:
給定 nums = [2, 7, 11, 15], target = 9
因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

演算法說明:我一同學去騰訊面試被問到了原題= =,這題我的思路是這樣的建立一個map索引,在掃描陣列的時候以值為key,索引位置為value插入到map中,然後掃描的時候觀察target減該值的key值是否在map中,在的話直接返回兩個的索引即可,不在的話,加入map。時間複雜度最壞的情況下就是O(nlogn),同樣可以使用hash map來優化。

程式碼:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int,int> mp;
        vector<int> res;
        for(int i=0;i<nums.size();i++){
            mp[nums[i]]=i;
        }
        map<int,int>::iterator it;
        for(int i=0;i<nums.size();i++){
            it=mp.find(target-nums[i]);
            if(it->second!=i&&it!=mp.end()) {
                res.push_back(i);
                res.push_back(it->second);
                break;
            }
        }
        return res;
    }
};

第十題 有效的數獨

題目描述:判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。

數字 1-9 在每一行只能出現一次。
數字 1-9 在每一列只能出現一次。
數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。

數獨部分空格內已填入了數字,空白格用 ‘.’ 表示。
示例 1:

輸入:
[
[“5”,”3”,”.”,”.”,”7”,”.”,”.”,”.”,”.”],
[“6”,”.”,”.”,”1”,”9”,”5”,”.”,”.”,”.”],
[“.”,”9”,”8”,”.”,”.”,”.”,”.”,”6”,”.”],
[“8”,”.”,”.”,”.”,”6”,”.”,”.”,”.”,”3”],
[“4”,”.”,”.”,”8”,”.”,”3”,”.”,”.”,”1”],
[“7”,”.”,”.”,”.”,”2”,”.”,”.”,”.”,”6”],
[“.”,”6”,”.”,”.”,”.”,”.”,”2”,”8”,”.”],
[“.”,”.”,”.”,”4”,”1”,”9”,”.”,”.”,”5”],
[“.”,”.”,”.”,”.”,”8”,”.”,”.”,”7”,”9”]
]
輸出: true

解題思路:一道細節題,就是判斷橫行每個區域的出現次數,所以建立三個陣列表來儲存即可,用於判斷是不是滿足每行每列每個區域只出現一次。那麼對於n*n的的矩陣掃描一遍即可,時間複雜度為O(n^2)

其實現程式碼如下:

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int rowtable[9][9]={0};
        int columtable[9][9]={0};
        int blocktable[9][9]={0};

        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){              
                if(board[i][j]!='.'){
                char temp=board[i][j]-'1';
                if((rowtable[i][temp]||columtable[j][temp]||blocktable[i/3*3+j/3][temp])==1) return false;
                rowtable[i][temp]=columtable[j][temp]=blocktable[i/3*3+j/3][temp]=1;
            }          
          }
        }
        return true;
    }
};

第十一題 旋轉影象

題目描述:給定一個 n × n 的二維矩陣表示一個影象。將影象順時針旋轉 90 度。
說明:
你必須在原地旋轉影象,這意味著你需要直接修改輸入的二維矩陣。請不要使用另一個矩陣來旋轉影象。
示例 1:
給定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],

原地旋轉輸入矩陣,使其變為:
[
[7,4,1],
[8,5,2],
[9,6,3]
]

解題演算法:因為要求是原地,即不使用額外的複雜度,所以在這個問題上我設定了一個temp,然後找出旋轉時,其座標對應的規律,然後按照題目的要求旋轉即可,其程式碼如下:

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int temp;
        int l=matrix.size();
        for(int i=0;i<matrix.size()/2;i++)
            for(int j=i;j<matrix.size()-i-1;j++){
                temp=matrix[l-1-j][i];
                matrix[l-1-j][i]=matrix[l-i-1][l-1-j];
                matrix[l-i-1][l-j-1]=matrix[j][l-1-i];
                matrix[j][l-1-i]=matrix[i][j];
                matrix[i][j]=temp;
            }
    }
};

至此初級演算法陣列篇就全部結束了,之後會更新字串篇等