- 島嶼數量
給你一個由 ‘1’(陸地)和 ‘0’(水)組成的的二維網格,請你計算網格中島嶼的數量。
島嶼總是被水包圍,並且每座島嶼只能由水平方向或豎直方向上相鄰的陸地連接形成。
本題可用BFS或DFS求解
class Solution {
private:
void dfs(vector<vector<char>>& grid, int r, int c) {
int nr = grid.size();
int nc = grid[0].size();
grid[r][c] = '0';
if (r - 1 >= 0 && grid[r-1][c] == '1') dfs(grid, r - 1, c);
if (r + 1 < nr && grid[r+1][c] == '1') dfs(grid, r + 1, c);
if (c - 1 >= 0 && grid[r][c-1] == '1') dfs(grid, r, c - 1);
if (c + 1 < nc && grid[r][c+1] == '1') dfs(grid, r, c + 1);
}
public:
int numIslands(vector<vector<char>>& grid) {
int nr = grid.size();
if (!nr) return 0;
int nc = grid[0].size();
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
dfs(grid, r, c);
}
}
}
return num_islands;
}
};
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int nr = grid.size();
if (!nr) return 0;
int nc = grid[0].size();
int num_islands = 0;
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
++num_islands;
grid[r][c] = '0';
queue<pair<int, int>> neighbors;
neighbors.push({r, c});
while (!neighbors.empty()) {
auto rc = neighbors.front();
neighbors.pop();
int row = rc.first, col = rc.second;
if (row - 1 >= 0 && grid[row-1][col] == '1') {
neighbors.push({row-1, col});
grid[row-1][col] = '0';
}
if (row + 1 < nr && grid[row+1][col] == '1') {
neighbors.push({row+1, col});
grid[row+1][col] = '0';
}
if (col - 1 >= 0 && grid[row][col-1] == '1') {
neighbors.push({row, col-1});
grid[row][col-1] = '0';
}
if (col + 1 < nc && grid[row][col+1] == '1') {
neighbors.push({row, col+1});
grid[row][col+1] = '0';
}
}
}
}
}
return num_islands;
}
};
- 數字範圍按位與
給定範圍 [m, n],其中 0 <= m <= n <= 2147483647,返回此範圍內所有數字的按位與(包含 m, n 兩端點)。
本題的精髓在於如何簡化位操作的次數。首先我們應該關注較小的數,如果位數不同直接從小數開始看即可。其次,當數位相同的時候,找到不相同的位賦值爲0即可
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
if (m == n || m == 0) {
return m;
} else if (floor(log(n)/log(2)) - floor(log(m)/log(2)) >= 1) {
return 0;
} else {
int xorResult = n ^ m;
int bits = floor(log(xorResult)/log(2)) + 1;
return (m >> bits) << bits;
}
}
};
- 快樂數
編寫一個算法來判斷一個數 n 是不是快樂數。
「快樂數」定義爲:對於一個正整數,每一次將該數替換爲它每個位置上的數字的平方和,然後重複這個過程直到這個數變爲 1,也可能是 無限循環 但始終變不到 1。如果 可以變爲 1,那麼這個數就是快樂數。
該題涉及到可能有循環的情況,因此用快慢指針檢測循環爲佳
class Solution {
public:
int bitSquareSum(int n) {
int sum = 0;
while(n > 0)
{
int bit = n % 10;
sum += bit * bit;
n = n / 10;
}
return sum;
}
bool isHappy(int n) {
int slow = n, fast = n;
do{
slow = bitSquareSum(slow);
fast = bitSquareSum(fast);
fast = bitSquareSum(fast);
}while(slow != fast);
return slow == 1;
}
};
- 移除鏈表元素
刪除鏈表中等於給定值 val 的所有節點。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* sentinel = new ListNode(0);
sentinel->next = head;
ListNode *prev = sentinel, *curr = head, *toDelete = nullptr;
while (curr != nullptr) {
if (curr->val == val) {
prev->next = curr->next;
toDelete = curr;
} else prev = curr;
curr = curr->next;
if (toDelete != nullptr) {
delete toDelete;
toDelete = nullptr;
}
}
ListNode *ret = sentinel->next;
delete sentinel;
return ret;
}
};
- 計數質數
統計所有小於非負整數 n 的質數的數量。
採用厄拉多塞篩法:先把所有設爲質數,然後依次排除其倍數
class Solution {
public:
int countPrimes(int n) {
int count = 0;
//初始默認所有數爲質數
vector<bool> signs(n, true);
for (int i = 2; i < n; i++) {
if (signs[i]) {
count++;
for (int j = i + i; j < n; j += i) {
//排除不是質數的數
signs[j] = false;
}
}
}
return count;
}
};
- 同構字符串
給定兩個字符串 s 和 t,判斷它們是否是同構的。
如果 s 中的字符可以被替換得到 t ,那麼這兩個字符串是同構的。
所有出現的字符都必須用另一個字符替換,同時保留字符的順序。兩個字符不能映射到同一個字符上,但字符可以映射自己本身。
本題有兩種方法:採用一個map映射已有的字符,後面每個檢查一遍是否映射相同。第二種方法是把字符對應轉換爲數字,然後比較兩串數字
class Solution {
public:
bool isIsomorphic(string s, string t)
{
if (s.empty() && t.empty())
return true;
for(int i = 0; i < s.size(); i++)
{
if( s.find(s[i]) != t.find(t[i]))
return false;
}
return true;
}
};
- 反轉鏈表
反轉一個單鏈表。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode *next, *ptr, *prev;
ptr = next = head;
prev = NULL;
while (ptr)
{
next = ptr->next;
ptr->next = prev;
prev = ptr;
ptr = next;
}
return prev;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
ListNode* ret = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return ret;
}
};