連結串列問題(演算法題)
阿新 • • 發佈:2020-11-13
1、從已排序的連結串列中刪除重複的單元。如:
輸入:1->1->2,輸出:1->2
如:
輸入:1->1->2->2->3,輸出 1->2->3
思路:
雙指標;
快指標先往後移動,如果快指標的值不等於慢指標的值,就釋放掉中間的指標空間,並且將慢指標next指向快指標,把快指標賦值給快指標。
Node* deleteDuplicationNodeFromSortedList(Node* &pHead) { if (pHead == NULL || pHead->next == NULL) {return pHead; } Node* node_slow = pHead; Node* node_fast = pHead; while (node_fast != NULL) { if (node_fast->value != node_slow->value) { freeNodeBetweenTwoPointer(node_slow, node_fast); node_slow->next = node_fast; node_slow= node_fast; } node_fast = node_fast->next; } if (node_slow->next != node_slow) { node_slow->next = node_fast; } return pHead; }
2、給定有序連結串列,刪除出現三次以上的元素。如:
輸入:1->1->2->3->3->3
返回:1->1->2
思路:雙指標
如果快指標的值不等於慢指標的值,那麼快慢指標就都往前走一步;如果遇到相同的數,快指標就繼續往前走,同時計數,超過三次以後就接著走直到碰到新數字以後修改慢指標的next
//這個還是有點複雜的,我想了挺久的 //主要難點在於如果沒有頭結點的連結串列進來第一個結點值是大於3的怎麼處理 //在慢指標的值不等於快指標的值的時候 Node* deleteDuplicationNodeThreeTimes(Node* &pHead) { if (pHead == NULL || pHead->next == NULL) { return pHead; } Node* node_slow = pHead; Node* node_before = node_slow; Node* node_fast = pHead->next; while (node_fast != NULL) { int delete_cnt = 1; int delete_num = node_fast->value; while (node_fast->next != NULL && delete_num == node_fast->next->value) { delete_cnt++; node_fast = node_fast->next; } if (delete_cnt >= 3) { node_slow->next = node_fast->next; } else { node_slow = node_fast; } node_fast = node_fast->next; } return pHead; }
Node* deleteDuplicationNodeThreeTimes(Node* &pHead) { if (pHead == NULL || pHead->next == NULL) { return pHead; } Node* node_slow = pHead; Node* node_before = node_slow; Node* node_fast = pHead->next; while (node_fast != NULL) { int cnt = 0; while (node_fast != NULL && node_slow->next->value == node_fast->value) { cnt++; node_fast = node_fast->next; } if (cnt >= 3) { node_slow->next = node_fast; } else { while (node_slow->next != node_fast) { node_slow = node_slow->next; } } } return pHead; }
3、給定無序連結串列,刪除出現三次以上的元素。
思路:hash演算法
兩次遍歷,第一次遍歷統計元素出現的次數,第二次遍歷檢視對應的value值出現次數是否大於3,是就刪除,否則就繼續走。
//預設傳進來的連結串列是帶有頭結點的 Node* deleteNodeThreeTimesFromUnordered(Node* &pHead) { if (pHead == NULL || pHead->next == NULL ) { return pHead; } unordered_map<int, int> hash_value; Node* node_tmp = pHead->next; while(node_tmp != NULL) { hash_value[ node_tmp->value ]++; node_tmp = node_tmp->next; } node_tmp = pHead; while (node_tmp->next != NULL) { if (hash_value[node_tmp->next->value] >= 3) { Node* node_free = node_tmp->next; node_tmp->next = node_free->next; free(node_free); } else { node_tmp = node_tmp->next; } } return pHead; }
4、無序列表,要求出現次數不能超過本身的value值。
思路:hash
兩次遍歷。第一次遍歷統計元素次數,第二次遍歷查看出現次數是否超過value值,超過就刪除,並且把對應的hash的value值減1.
Node* deleteNodeOverValueTimesFromUnordered(Node* &pHead) { if (pHead == NULL || pHead->next == NULL) { return pHead; } unordered_map<int, int> hash_value; Node* node_tmp = pHead->next; while (node_tmp != NULL) { hash_value[ node_tmp->value ]++; node_tmp = node_tmp->next; } node_tmp = pHead; while (node_tmp->next != NULL) { if (node_tmp->next->value < hash_value[ node_tmp->next->value ] ) { hash_value[ node_tmp->next->value ]--; Node* node_free = node_tmp->next; node_tmp->next = node_free->next; free(node_free); } else { node_tmp = node_tmp->next; } } return pHead; }