數組
是一種基本的數據結構,用於按順序存儲元素的集合
。可是元素能夠隨機存取,由於數組中的每一個元素均可以經過數組索引
來識別。ios
數組能夠有一個或多個維度。這裏咱們從一維數組
開始,它也被稱爲線性數組。這裏有一個例子:c++
在上面的例子中,數組 A 中有 6 個元素。也就是說,A 的長度是 6 。咱們可使用 A[0] 來表示數組中的第一個元素。所以,A[0] = 6 。相似地,A[1] = 3,A[2] = 8,依此類推。git
數組中的操做編程
讓咱們來看看數組的用法:數組
#include <iostream> int main() { // 1. Initialize int a0[5]; int a1[5] = {1, 2, 3}; // other element will be set as the default value // 2. Get Length int size = sizeof(a1) / sizeof(*a1); cout << "The size of a1 is: " << size << endl; // 3. Access Element cout << "The first element is: " << a1[0] << endl; // 4. Iterate all Elements cout << "[Version 1] The contents of a1 are:"; for (int i = 0; i < size; ++i) { cout << " " << a1[i]; } cout << endl; cout << "[Version 2] The contents of a1 are:"; for (int& item: a1) { cout << " " << item; } cout << endl; // 5. Modify Element a1[0] = 4; // 6. Sort sort(a1, a1 + size); }
正如咱們在上一篇文章中提到的,數組具備固定的容量
,咱們須要在初始化時指定數組的大小。有時它會很是不方便並可能形成浪費。數據結構
所以,大多數編程語言都提供內置的動態數組
,它仍然是一個隨機存取的列表數據結構,但大小是可變的
。例如,在 C++ 中的 vector
,以及在 Java 中的 ArrayList
。dom
動態數組中的操做編程語言
讓咱們來看看動態數組的用法:spa
#include <iostream> int main() { // 1. initialize vector<int> v0; vector<int> v1(5, 0); // 2. make a copy vector<int> v2(v1.begin(), v1.end()); vector<int> v3(v2); // 2. cast an array to a vector int a[5] = {0, 1, 2, 3, 4}; vector<int> v4(a, *(&a + 1)); // 3. get length cout << "The size of v4 is: " << v4.size() << endl; // 4. access element cout << "The first element in v4 is: " << v4[0] << endl; // 5. iterate the vector cout << "[Version 1] The contents of v4 are:"; for (int i = 0; i < v4.size(); ++i) { cout << " " << v4[i]; } cout << endl; cout << "[Version 2] The contents of v4 are:"; for (int& item : v4) { cout << " " << item; } cout << endl; cout << "[Version 3] The contents of v4 are:"; for (auto item = v4.begin(); item != v4.end(); ++item) { cout << " " << *item; } cout << endl; // 6. modify element v4[0] = 5; // 7. sort sort(v4.begin(), v4.end()); // 8. add new element at the end of the vector v4.push_back(-1); // 9. delete the last element v4.pop_back(); }
給定一個整數類型的數組 nums
,請編寫一個可以返回數組「中心索引」的方法。3d
咱們是這樣定義數組中心索引的:數組中心索引的左側全部元素相加的和等於右側全部元素相加的和。
若是數組不存在中心索引,那麼咱們應該返回 -1。若是數組有多箇中心索引,那麼咱們應該返回最靠近左邊的那一個。
示例 1:
輸入: nums = [1, 7, 3, 6, 5, 6] 輸出: 3 解釋: 索引3 (nums[3] = 6) 的左側數之和(1 + 7 + 3 = 11),與右側數之和(5 + 6 = 11)相等。 同時, 3 也是第一個符合要求的中心索引。
示例 2:
輸入: nums = [1, 2, 3] 輸出: -1 解釋: 數組中不存在知足此條件的中心索引。
說明:
nums
的長度範圍爲 [0, 10000]
。nums[i]
將會是一個範圍在 [-1000, 1000]
的整數。class Solution{ public: int pivotIndex(vector<int>& nums){ if(nums.size() == 0) return -1; int sum = accumulate(nums.begin(), nums.end(), 0); int leftSum = 0; for(int i=0; i<nums.size(); i++) if(leftSum == sum-leftSum-nums[i]) return i; else leftSum += nums[i]; return -1; } };
在一個給定的數組nums
中,老是存在一個最大元素 。
查找數組中的最大元素是否至少是數組中每一個其餘數字的兩倍。
若是是,則返回最大元素的索引,不然返回-1。
示例 1:
輸入: nums = [3, 6, 1, 0] 輸出: 1 解釋: 6是最大的整數, 對於數組中的其餘整數, 6大於數組中其餘元素的兩倍。6的索引是1, 因此咱們返回1.
示例 2:
輸入: nums = [1, 2, 3, 4] 輸出: -1 解釋: 4沒有超過3的兩倍大, 因此咱們返回 -1.
提示:
nums
的長度範圍在[1, 50]
.nums[i]
的整數範圍在 [0, 99]
.#include <iostream> #include <vector> using namespace std; /// Linear Scan /// Time Complexity: O(n) /// Space Complexity: O(1) class Solution{ public: int dominantIndex(vector<int>& nums){ int maxNum = *max_element(nums.begin(), nums.end()); int res = -1; for(int i = 0; i< nums.size(); i++) if(nums[i] != maxNum){ if(maxNum < 2*nums[i]) return -1; } else res = i; return res; } };
給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。
最高位數字存放在數組的首位, 數組中每一個元素只存儲一個數字。
你能夠假設除了整數 0 以外,這個整數不會以零開頭。
示例 1:
輸入: [1,2,3] 輸出: [1,2,4] 解釋: 輸入數組表示數字 123。
示例 2:
輸入: [4,3,2,1] 輸出: [4,3,2,2] 解釋: 輸入數組表示數字 4321。
#include <iostream> #include <vector> using namespace std; /// Ad Hoc /// Time Complexity: O(n) /// Space Complexity: O(1) class Solution{ public: vector<int> plusOne(vector<int>& digits){ digits[digits.size() -1] ++; for(int i=digits.size()-1; i>=1; i--) if(digits[i] == 10){ digits[i] = 0; digits[i-1] ++; } if(digits[0] == 10){ digits[0] = 0; digits.insert(digits.begin(), 1); } return digits; } }
相似於一維數組,二維數組
也是由元素的序列組成。可是這些元素能夠排列在矩形網格中而不是直線上。
示例
#include <iostream> template <size_t n, size_t m> void printArray(int (&a)[n][m]) { for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cout << a[i][j] << " "; } cout << endl; } } int main() { cout << "Example I:" << endl; int a[2][5]; printArray(a); cout << "Example II:" << endl; int b[2][5] = {{1, 2, 3}}; printArray(b); cout << "Example III:"<< endl; int c[][5] = {1, 2, 3, 4, 5, 6, 7}; printArray(c); cout << "Example IV:" << endl; int d[][5] = {{1, 2, 3, 4}, {5, 6}, {7}}; printArray(d); }
原理
在一些語言中,多維數組其實是在內部
做爲一維數組實現的,而在其餘一些語言中,實際上
根本沒有多維數組
。
1. C++ 將二維數組存儲爲一維數組。
下圖顯示了大小爲 M * N 的數組 A 的實際結構:
2. 在Java中,二維數組其實是包含着 M 個元素的一維數組,每一個元素都是包含有 N 個整數的數組。
下圖顯示了 Java 中二維數組 A 的實際結構:
動態二維數組
與一維動態數組相似,咱們也能夠定義動態二維數組。 實際上,它能夠只是一個嵌套的動態數組。 你能夠本身嘗試一下。
給定一個含有 M x N 個元素的矩陣(M 行,N 列),請以對角線遍歷的順序返回這個矩陣中的全部元素,對角線遍歷以下圖所示。
示例:
輸入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] 輸出: [1,2,4,7,5,3,6,8,9]
解釋:
說明:
#include <iostream> #include <vector> using namespace std; /// Simulation /// Time Complexity: O(n * m) /// Space Complexity: O(1) class Solution { private: int n, m; public: vector<int> findDiagonalOrder(vector<vector<int>> &matrix) { vector<int> res; n = matrix.size(); if (n == 0) return res; m = matrix[0].size(); int x = 0, y = 0; int nextX, nextY; bool up = true; while (true) { res.push_back(matrix[x][y]); if (up) nextX = x - 1, nextY = y + 1; else nextX = x + 1, nextY = y - 1; if(inArea(nextX, nextY)) x = nextX, y = nextY; else if(up){ if(inArea(x, y+1)) y++; else x++; up = false; } else{ if(inArea(x+1, y)) x++; else y++; up = true; } if(!inArea(x, y)) break; } return res; } private: bool inArea(int x, int y){ return x>=0 && x<n && y >=0 && y<m; } }; void print_vec(const vector<int>& vec){ for(int e: vec) cout << e << " "; cout << endl; } int main(){ vector<vector<int>> matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; print_vec(Solution().findDiagonalOrder(matrix)); return 0; }
給定一個包含 m x n 個元素的矩陣(m 行, n 列),請按照順時針螺旋順序,返回矩陣中的全部元素。
示例 1:
輸入: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] 輸出: [1,2,3,6,9,8,7,4,5]
示例 2:
輸入: [ [1, 2, 3, 4], [5, 6, 7, 8], [9,10,11,12] ] 輸出: [1,2,3,4,8,12,11,10,9,5,6,7]
/// Source : https://leetcode.com/problems/spiral-matrix/description/ /// Author : liuyubobobo /// Time : 2018-04-24 #include <iostream> #include <vector> using namespace std; /// Simulation /// Time Complexity: O(n^2) /// Space Complexity: O(n^2) class Solution { private: int d[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; int N, M; public: vector<int> spiralOrder(vector<vector<int>>& matrix) { N = matrix.size(); if(N == 0) return {}; M = matrix[0].size(); if(M == 0) return {}; vector<vector<bool>> visited(N, vector<bool>(M, false)); int curd = 0, curx = 0, cury = 0; vector<int> res; while(res.size() < N * M){ if(!visited[curx][cury]) { res.push_back(matrix[curx][cury]); visited[curx][cury] = true; } int nextx = curx + d[curd][0]; int nexty = cury + d[curd][1]; if(inArea(nextx, nexty) && !visited[nextx][nexty]){ curx = nextx; cury = nexty; } else curd = (curd + 1) % 4; } return res; } private: bool inArea(int x, int y){ return x >= 0 && x < N && y >= 0 && y < M; } }; void print_vec(const vector<int>& vec){ for(int e: vec) cout << e << " "; cout << endl; } int main() { vector<vector<int>> matrix1 = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }; print_vec(Solution().spiralOrder(matrix1)); return 0; }
給定一個非負整數 numRows,生成楊輝三角的前 numRows 行。
在楊輝三角中,每一個數是它左上方和右上方的數的和。
示例:
輸入: 5 輸出: [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ]
#include <iostream> #include <vector> using namespace std; /// Simulation (Dynamic Programming) /// Time Complexity: O(n^2) /// Space Complexity: O(1) class Solution{ public: vector<vector<int>> generate(int numRows){ vector<vector<int>> res; if(numRows <= 0) return res; res.push_back({1}); for(int i=1; i<numRows; i++){ vector<int> row; row.push_back(1); for(int j=1; j<i; j++) row.push_back(res[i-1][j-1]+res[i-1][j]); row.push_back(1); res.push_back(row); } return res; } };