417. 太平洋-大西洋海流の問題
水は高い場所に流れます。まず、2つの海祥が高い場所に流れる住所を記録し、次にそれらの結合した領域を出力します
static const int dirs[4][2] = {
{
-1, 0}, {
1, 0}, {
0, -1}, {
0, 1}};
class Solution {
public:
vector<vector<int>> heights;
void dfs(int row, int col, vector<vector<bool>> & ocean) {
int m = ocean.size();
int n = ocean[0].size();
if (ocean[row][col]) {
return;
}
ocean[row][col] = true;
for (int i = 0; i < 4; i++) {
int newRow = row + dirs[i][0], newCol = col + dirs[i][1];
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && heights[newRow][newCol] >= heights[row][col]) {
dfs(newRow, newCol, ocean);
}
}
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
this->heights = heights;
int m = heights.size();
int n = heights[0].size();
vector<vector<bool>> pacific(m, vector<bool>(n, false));
vector<vector<bool>> atlantic(m, vector<bool>(n, false));
for (int i = 0; i < m; i++) {
dfs(i, 0, pacific);
}
for (int j = 1; j < n; j++) {
dfs(0, j, pacific);
}
for (int i = 0; i < m; i++) {
dfs(i, n - 1, atlantic);
}
for (int j = 0; j < n - 1; j++) {
dfs(m - 1, j, atlantic);
}
vector<vector<int>> result;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
result.push_back({
i,j});
}
}
}
return result;
}
};
24. リンクリスト内のノードを 2 つずつ交換します
紙に絵を描く
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode*_head=new ListNode(0);
_head->next=head;
ListNode*cur=_head;
while(cur->next!=nullptr&&cur->next->next!=nullptr){
ListNode*tmp=cur->next->next->next;
ListNode*tmp1=cur->next->next;
cur->next->next->next=cur->next;
cur->next->next=tmp;
cur->next=tmp1;
cur=cur->next->next;
}
return _head->next;
}
};
19. リンクリストの最後の N ノードを削除します
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode*_head=new ListNode(0);
_head->next=head;
ListNode*cur=_head;
int size=0;
while(cur->next!=nullptr){
cur=cur->next;
size++;
}
size=size-n;
cur=_head;
while(size--){
cur=cur->next;
}
cur->next=cur->next->next;
return _head->next;
}
};
別の書き方もあります。ファストポインタとスローポインタをダブルにして、ファストポインタを最初に動かし、次にスローポインタとファストポインタを一緒に動かし、ファストポインタがnullのときにスローポインタを削除して、ヘッドノードに戻ります。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* slow = dummyHead;
ListNode* fast = dummyHead;
while(n-- && fast != NULL) {
fast = fast->next;
}
fast = fast->next; // fast再提前走一步,因为需要让slow指向删除节点的上一个节点
while (fast != NULL) {
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
// ListNode *tmp = slow->next; C++释放内存的逻辑
// slow->next = tmp->next;
// delete nth;
return dummyHead->next;
}
};
インタビューの質問 02.07. リンクされたリストの交差
非常に興味深い解決策です。通常の解決策は、最初にそれらすべてを調べてから、全員のサイズを調べます。次に、両側の
ポインタを短いポインタが比較を開始する位置に移動し、それらが一致していれば戻ります。が等しい、または等しくない場合
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
};