反正就是各种链表
1、定义单链表/双链表
struct ListNode {
int val;
ListNode* next;
ListNode(int x) :val(x),next(NULL) {}
};
struct ListNode{
ListNode* pre;
ListNode* next;
int value;
ListNode(int _key, int _value):
pre(nullptr),
next(nullptr),
value(_value)
{}
};
2、单链表的反转
属于是必知必会题了~
ListNode* ReverseList(ListNode* pHead) {
ListNode* pre = nullptr;
ListNode* cur = pHead;
ListNode* nex = nullptr;
while (cur) {
nex = cur->next;
cur->next = pre;
pre = cur;
cur = nex;
}
return pre;
}
3、判断链表中是否有环
经典之快慢指针
bool hasCycle(ListNode *head) {
if(head == nullptr){
return false;
}
ListNode* fast = head;
ListNode* slow = head;
while(fast != nullptr && fast->next != nullptr){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
return true;
}
}
return false;
}
4、链表中环的入口结点
借助一下set
ListNode* EntryNodeOfLoop(ListNode* pHead) {
set<ListNode*> s ;
while (pHead != nullptr) {
if (!s.empty()) {
set<ListNode*>::iterator it = s.begin();
it = s.find(pHead);
if (it != s.end()) {
return pHead;
}
}
s.insert(pHead);
pHead = pHead->next;
}
return pHead;
}
5、两个链表的第一个公共结点
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode *ta = pHead1, *tb = pHead2;
while (ta != tb) {
ta = ta ? ta->next : pHead2;
tb = tb ? tb->next : pHead1;
}
return ta;
}
6、合并两个排序的链表
ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
if (pHead1 == nullptr && pHead2 == nullptr) {
return pHead1;
}
else if (pHead2 == nullptr && pHead1 != nullptr) {
return pHead1;
}
else if (pHead1 == nullptr && pHead2 != nullptr) {
return pHead2;
}
ListNode* pre = pHead1;
vector<int> v;
while (pre != nullptr) {
v.push_back(pre->val);
pre = pre->next;
}
pre = pHead2;
while (pre != nullptr) {
v.push_back(pre->val);
pre = pre->next;
}
sort(v.begin(), v.end());
ListNode* head;
head = new ListNode(v[0]);
ListNode* p = nullptr;
head->next = p;
ListNode* cur = head;
for (size_t i = 1; i < v.size(); ++i) {
p = new ListNode(v[i]);
cur->next = p;
cur = cur->next;
}
return head;
}
7、 合并k个已排序的链表
ListNode* mergeKLists(vector<ListNode*>& lists) {
if (lists.empty()) {
return nullptr;
}
vector<int> cur;
for (size_t i = 0; i < lists.size(); ++i) {
ListNode* head = lists[i];
while (head) {
cur.push_back(head->val);
head = head->next;
}
}
sort(cur.begin(), cur.end());
ListNode* ret = new ListNode(0);
ListNode* pre = ret;
for (size_t i = 0; i < cur.size(); ++i) {
pre->next = new ListNode(cur[i]);
pre = pre->next;
}
return ret->next;
}
8、单链表的排序
ListNode* sortInList(ListNode* head) {
if (head == nullptr) {
return nullptr;
}
vector<int> v;
ListNode* next = head->next;
while (head != nullptr) {
v.push_back(head->val);
head = next;
if (next != nullptr) {
next = head->next;
}
else {
next = nullptr;
}
}
sort(v.begin(), v.end());
ListNode* pHead = new ListNode(v[0]);
pHead->next = nullptr;
ListNode* cur = pHead;
for (size_t i = 1; i < v.size(); ++i) {
ListNode* pre = new ListNode(v[i]);
pre->next = nullptr;
cur->next = pre;
cur = cur->next;
}
return pHead;
}
9、链表中的节点每k个一组翻转
ListNode* reverseKGroup(ListNode* head, int k) {
if (head == nullptr) {
return nullptr;
}
else if (k == 0) {
return head;
}
ListNode* ret = new ListNode(0);
stack<int> s;
int num = 0;
ListNode* cur = head;
ListNode* pre = ret;
while (cur) {
while (num < k && cur != nullptr) {
s.push(cur->val);
cur = cur->next;
num++;
}
if (s.size() == k) {
while (!s.empty()) {
pre->next = new ListNode(s.top());
s.pop();
pre = pre->next;
}
}
else {
stack<int> cur_s;
while (!s.empty()) {
cur_s.push(s.top());
s.pop();
}
while (!cur_s.empty()) {
pre->next = new ListNode(cur_s.top());
cur_s.pop();
pre = pre->next;
}
}
num = 0;
}
return ret->next;
}
10、两个链表生成相加链表
ListNode* addInList(ListNode* head1, ListNode* head2) {
if (head1 == nullptr && head2 != nullptr) {
return head2;
}
else if ((head1 != nullptr && head2 == nullptr) || (head1 == nullptr && head2 == nullptr)) {
return head1;
}
stack<int> s1;
stack<int> s2;
while (head1 != nullptr) {
s1.push(head1->val);
head1 = head1->next;
}
while (head2 != nullptr) {
s2.push(head2->val);
head2 = head2->next;
}
stack<int> ret_s;
int num = max(s1.size(), s2.size());
int cur = 0; //标记是否需要进位
int ret = 0;
for (int i = 0; i < num; ++i) {
if (s1.empty()) {
s1.push(0);
}
else if (s2.empty()) {
s2.push(0);
}
ret = s1.top() + s2.top();
//判断是否需要进位
if (cur == 1) {
ret += 1;
cur = 0;
}
//判断下次是否需要进位
if (ret >= 10) {
cur = 1;
ret_s.push(ret % 10);
}
else {
ret_s.push(ret);
}
s1.pop();
s2.pop();
}
if (cur == 1) {
ret_s.push(1);
}
ListNode* pHead = new ListNode(ret_s.top());
ListNode* pCur = nullptr;
pCur = pHead;
pHead->next = nullptr;
ret_s.pop();
size_t size = ret_s.size();
for (size_t i = 0; i < size; ++i) {
ListNode* node = new ListNode(ret_s.top());
pCur->next = node;
pCur = node;
ret_s.pop();
}
return pHead;
}
11、删除有序链表中重复的元素-I
去重!
ListNode* deleteDuplicates(ListNode* head) {
if (head == nullptr) {
return nullptr;
}
set<int> s;
ListNode* ret = new ListNode(0);
ListNode* cur = head;
ListNode* pre = ret;
while (cur) {
s.insert(cur->val);
cur = cur->next;
}
for (set<int>::iterator it = s.begin(); it != s.end(); ++it) {
pre->next = new ListNode(*it);
pre = pre->next;
}
return ret->next;
}
12、删除有序链表中重复的元素-II
有重复就删除!
ListNode* deleteDuplicates2(ListNode* head) {
if (head == nullptr) {
return nullptr;
}
ListNode* ret = new ListNode(0);
ListNode* pre = ret;
ListNode* cur = head;
map<int, int> m;
while (cur) {
map<int, int>::iterator it = m.find(cur->val);
if (it != m.end()) {
it->second += 1;
}
else {
m.insert(make_pair(cur->val, 1));
}
cur = cur->next;
}
for (map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
if (it->second == 1) {
ListNode* nex = new ListNode(it->first);
pre->next = nex;
pre = pre->next;
}
}
return ret->next;
}
13、链表内指定区间反转
ListNode* reverseBetween(ListNode* head, int m, int n) {
if (head == nullptr || m == n) {
return head;
}
ListNode* ret = new ListNode(0);
ListNode* cur = ret;
vector<int> v;
stack<int> s;
int num = 1;
while (head != nullptr) {
if (num < m) {
v.push_back(head->val);
}
else if (num >= m && num <= n) {
s.push(head->val);
}
else {
while (!s.empty()) {
v.push_back(s.top());
s.pop();
}
v.push_back(head->val);
}
head = head->next;
num++;
}
if (!s.empty()) {
while (!s.empty()) {
v.push_back(s.top());
s.pop();
}
}
for (size_t i = 0; i < v.size(); ++i) {
ListNode* pre = new ListNode(v[i]);
cur->next = pre;
cur = cur->next;
}
return ret->next;
}
14、 排序奇升偶降链表
NC207 排序奇升偶降链表
面试题,要求只能通过链表操作来完成!!!(不然可以放到数组里sort)
ListNode* sortLinkedList(ListNode* head) {
if (head == nullptr) {
return nullptr;
}
ListNode* pre = head;
ListNode* jHead = new ListNode(0);
ListNode* oHead = new ListNode(0);
//奇数位升序,偶数位降序, 返回升序
ListNode* cur1 = jHead;
int num = 1;
while (pre) {
if (num % 2 != 0) {
ListNode* node = new ListNode(pre->val);
cur1->next = node;
cur1 = cur1->next;
}
else if (num % 2 == 0) {
ListNode* cur2 = oHead;
ListNode* node = new ListNode(pre->val);
if(cur2->next == nullptr){
cur2->next = node;
}
else {
ListNode* next = cur2->next;
cur2->next = node;
node->next = next;
}
}
pre = pre->next;
num++;
}
//两个有序链表合并
ListNode* pre2 = oHead->next;
while (pre2) {
ListNode* pre1 = jHead->next;
ListNode* cur = jHead;
while (pre1) {
if (pre2->val < pre1->val) {
ListNode* node = new ListNode(pre2->val);
cur->next = node;
node->next = pre1;
break;
}
if (pre1->next != nullptr) {
if ((pre2->val > pre1->val) && (pre2->val < pre1->next->val)) {
ListNode* next = pre1->next;
ListNode* node = new ListNode(pre2->val);
pre1->next = node;
node->next = next;
break;
}
}
else {
ListNode* node = new ListNode(pre2->val);
pre1->next = node;
node->next = nullptr;
break;
}
pre1 = pre1->next;
cur = cur->next;
}
pre2 = pre2->next;
}
return jHead->next;
}
15、判断一个链表是否为回文结构
bool isPail(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return true;
}
vector<int> vec;
while (head) {
vec.push_back(head->val);
head = head->next;
}
for (size_t i = 0; i < sizeof(vec); ++i) {
if (vec[i] == vec[vec.size() - 1 - i]) {
if (i >= vec.size() - 1 - i) {
break;
}
else {
continue;
}
}
else {
return false;
}
}
return true;
}
16、链表的奇偶重排
ListNode* oddEvenList(ListNode* head) {
if (head == nullptr) {
return head;
}
ListNode* jHead = new ListNode(0);
ListNode* oHead = new ListNode(0);
ListNode* cur1 = jHead;
ListNode* cur2 = oHead;
int num = 1;
while (head) {
ListNode* node = new ListNode(head->val);
if (num % 2 != 0) {
cur1->next = node;
cur1 = cur1->next;
}
else{
cur2->next = node;
cur2 = cur2->next;
}
num++;
head = head->next;
}
cur1->next = oHead->next;
return jHead->next;
}
17、给单链表加一
ListNode* reverseList(ListNode* head) {
ListNode* pre = head;
ListNode* cur = nullptr;
ListNode* nex = nullptr;
while (pre) {
nex = pre->next;
pre->next = cur;
cur = pre;
pre = nex;
}
return cur;
}
ListNode* plusOne(ListNode* head) {
if (head == nullptr) {
ListNode* node = new ListNode(1);
return node;
}
ListNode* pHead = reverseList(head);
ListNode* cur = pHead;
int cur_num = 0; //进位标识位
int num = 0; //记录数据
num = pHead->val + 1;
if (num == 10) {
cur_num = 1;
pHead->val = 0;
while (cur_num) {
if (cur->next == nullptr) {
ListNode* node = new ListNode(1);
cur->next = node;
cur_num = 0;
}
else {
num = cur->next->val + 1;
if (num < 10) {
cur->next->val = num;
cur_num = 0;
}
else {
cur->next->val = 0;
}
}
cur = cur->next;
}
}
else {
pHead->val = num;
}
return reverseList(pHead);
}
18、环形链表的约瑟夫问题
struct SListNode {
int val;
SListNode* pre;
SListNode* nex;
SListNode(int x) :
val(x),
pre(nullptr),
nex(nullptr)
{}
};
int ysf(int n, int m) {
SListNode* root = new SListNode(0);
SListNode* cur = root;
for (int i = 1; i <= n; ++i) {
SListNode* node = new SListNode(i);
cur->nex = node;
node->pre = cur;
cur = cur->nex;
}
root = root->nex;
root->pre = cur;
cur->nex = root;
cur = cur->nex;
while (cur->nex != cur) {
for (int i = 1; i <= m; ++i) {
cur = cur->nex;
}
SListNode* node = cur->pre->pre;
cur->pre = node;
node->nex = cur;
}
return cur->val;
}
19、划分链表
ListNode* partition(ListNode* head, int x) {
if (head == nullptr) {
return head;
}
ListNode* cur = head;
ListNode* ret = new ListNode(0);
ListNode* head_s = new ListNode(0);
ListNode* head_b = new ListNode(0);
ListNode* cur_a = head_s;
ListNode* cur_b = head_b;
int size_s = 0;
int size_b = 0;
while (cur) {
if (cur->val < x) {
ListNode* node = new ListNode(cur->val);
cur_a->next = node;
cur_a = cur_a->next;
size_s++;
}
else if (cur->val >= x) {
ListNode* node = new ListNode(cur->val);
cur_b->next = node;
cur_b = cur_b->next;
size_b++;
}
cur = cur->next;
}
if (size_s && size_b) {
cur_a->next = head_b->next;
ret->next = head_s->next;
}
else {
ret->next = head;
}
return ret->next;
}
20、删除链表的倒数第n个节点
ListNode* removeNthFromEnd(ListNode* head, int n) {
// write code here
ListNode* ret = new ListNode(0);
ret->next = head;
ListNode* slow = ret;
ListNode* cur = head;
ListNode* pre = head;
while(n > 0){
cur = cur->next;
n--;
}
while(cur){
cur = cur->next;
slow = slow->next;
pre = pre->next;
}
slow->next = pre->next;
return ret->next;
}