以下題目**於leetcode
有兩個鍊錶,它們表示逆序的兩個非負數。計算出兩個數的和之後,同樣逆序輸出作為乙個鍊錶
比如:(2->1->3)+ (5->6->4)
得到:7->0->8
//add two numbers
class solution
if (carry > 0)
prev->next = new listnode(carry);
return dummy.next;
}};
把鍊錶中m到n的部分反轉(1<=m<=n<=length)。
注意要求:在原地反轉,也就是不能申請額外的空間,且只能遍歷一遍。
比如:1->2->3->4->5->nullptr,m=2,n=4
return 1->4->3->2->5->nullptr
1<=m<=n<=length
listnode* reversebetween(listnode *head, int
m, int n)
listnode* const head2 = prev;
prev = head2->next;
listnode* cur = prev->next;
for (int i = m; i < n; i++)
return dummy.next;
}
給定乙個單鏈表和乙個x,把鍊錶中小於x的放到前面,大於等於x的放到後面,每部分元素的原始相對位置不變。
遍歷一遍鍊錶,把小於x的都掛到head1後,把大於等於x的都放到head2後,最後再把大於等於的鍊錶掛到小於鍊錶的後面就可以了。
listnode* partition(listnode* head, int x)
else
}left_cur->next = right_dummy.next;
right_cur->next = nullptr;
return left_dummy.next;
}
去除鍊錶中的重複元素,使之只出現一次。
比如:1->1->2,return 1->2
1->1->2->3->3,return 1->2->3
listnode *delduplicates(listnode* head)
else
prev = cur;
}return head;
}
去除鍊錶中的重複元素,使之一次也不出現。
比如:1->2->3->3->4->4->5 return 1->2->5
1->1->1->2->3 return 2->3
//使煉表中重複的元素一次也不出現
listnode* delduplicate(listnode* head)
delete head;
return delduplicate(p);
}else
}
在k位置處旋轉鍊錶
比如:->2->3->4->5 k = 2
return 4->5->1->2->3
先遍歷一遍,得出鍊錶長度len.注意k可能大於len,所以令 k%=len,,將尾節點next指標指向首節點,形成乙個環,接著往後走len-k步,從這裡斷開環,就是要求的結果了。
listnode* rotateright(listnode* head, int k)
k = len - k%len;
p->next = head; // 首尾相連構成環
for (int step = 0; step < k; step++)
head = p->next; //新的首節點
p->next = nullptr;//斷開環
return head;
}
成對交換節點
比如:1->2->3->4 return 2->1->4->3
題目規定不能直接交換兩個節點的值,所以我們只能交換兩個節點。
給定乙個鍊錶,把最後乙個結點插入到第1個結點後,倒數第二個結點插入到第2個結點後,倒數第三個結點插入到第3個結點後,以此類推……
找到中間節點,將後面的鍊錶reverse,再合併前後的兩部分
//找到中間位置,翻轉後面的鍊錶並合併
void recorderlist(listnode *head)
prev->next =
null;//cut at middle
slow = reverse(slow);
//merge two lists
listnode *cur = head;
while (cur->next)
cur->next = slow;
}listnode* reverse(listnode* head)
return dummy.next;
}
把原始鍊錶k個k個的反轉,如果最後剩餘的不到k個結點,那麼保持不變。
這道題讓我們以每k個為一組來翻轉鍊錶,實際上是把原鍊錶分成若干小段,然後分別對其進行翻轉,那麼肯定總共需要兩個函式,乙個是用來分段的,乙個是用來翻轉的,我們就以題目中給的例子來看,對於給定鍊錶1->2->3->4->5,一般在處理鍊錶問題時,我們大多時候都會在開頭再加乙個dummy node,因為翻轉鍊錶時頭結點可能會變化,為了記錄當前最新的頭結點的位置而引入的dummy node,那麼我們加入dummy node後的鍊錶變為-1->1->2->3->4->5,如果k為3的話,我們的目標是將1,2,3翻轉一下,那麼我們需要一些指標,pre和next分別指向要翻轉的鍊錶的前後的位置,然後翻轉後pre的位置更新到如下新的位置:
-1->1->2->3->4->5
| |
pre next
-1->3->2->1->4->5
| |
pre next
//將鍊錶元素k個k個的旋轉
listnode* reversekgroup(listnode* head, int k)
listnode dummy(-1);
listnode* prev = &dummy, *cur = head;
dummy.next = head;
int i = 0;
while (cur)
else
}return dummy.next;
}listnode* reverseonegroup(listnode* prev, listnode* next)
return
last;
}
設計並實現乙個支援get和set操作的快取:
get(key) - 存在時返回其值,否則返回-1;
set(key) - 不存在時插入新值,存在時更新其值,注意當容量滿時,需刪除最長時間沒有訪問的key,將其刪除,並插入新的key。
這題的大致思路就是用乙個hash表來儲存已經存在的key, 然後用另外乙個線性容器來儲存其key-value值, 我們可以選擇鍊錶list, 因為需要調整結點的位置, 而鍊錶可以在o(1)時間移動結點的位置, 陣列則需要o(n).
如果新來乙個set請求, 我們先去查hash表
1. 如果已經存在了這個key, 那麼我們需要更新其value, 然後將其在list的結點位置移動到鍊錶首部.
2. 如果不存在這個key, 那麼我們需要在hash表和煉表中都新增這個值, 並且如果新增之後鍊錶長度超過最大長度, 我們需要將鍊錶尾部的節點刪除, 並且刪除其在hash表中的記錄
如果來了乙個get請求, 我們仍然先去查hash表, 如果key存在hash表中, 那麼需要將這個結點在鍊錶的中的位置移動到鍊錶首部.否則返回-1.
class lrucache
int get(int key)
void
set(int key, int value)
//插入新節點到鍊錶頭部,並且在map中增加該節點
cachelist.push_front(cachenode(key, value));
cachemap[key] = cachelist.begin();
}else
}private:
struct cachenode
};list
cachelist;
unordered_map
::iterator> cachemap;
int _capacity;
};
鍊錶的相關筆試面試題
1.反轉乙個鍊錶,不能申請新空間 思路 反轉乙個鍊錶,不申請新空間,即將乙個鍊錶通過頭插 頭刪的方法進行替換 反轉前 1 2 3 4 5 null 反轉後 null 5 4 3 2 1 struct listnode reverselist struct listnode head return r...
關於鍊錶的一些筆試面試題
1.逆序列印單鏈表 遞迴 include include include typedef char linktype typedef struct linknodelinknode void linklistreverseprint linknode head if head next null p...
IT筆試面試題整理 反轉鍊錶
試題描述 定義乙個函式,輸入乙個鍊錶的頭節點,反轉該鍊錶並輸出反轉後鍊錶的頭節點 參考 方法一 1 public static link reverselinklist link head 217 cur.next pre 當current為最後乙個節點時,back為null,所以要再指向前節點 1...