0928美团面试真题。
几天没做题,真的手生…脑子确实很紧张,有点儿转不动。最后当场挂面了,面对现实,平静接受吧。
事后遭遇YZT嘲讽,哈哈哈,倒也没什么,继续加油就完事了…能走到哪一步就算哪一步吧!😳
删除有序链表中重复出现的节点
如输入:1,2,3,3,4,4,5
则输出:1,2,5
现在脑子清醒点了,面试中:
第一步应该是审题
,问清楚要求…然后抛出一两个可行的解(即使笨拙,但可靠),然后细化一些内容。
第二,先论证解法是否可行
,切勿急忙忙敲下代码。
第三,将想法付诸代码。如果在牛客上写不出来,调试不成功,通常不给本地调试机会。还是得画图逐步来分析(切记:以后面试一定要带上纸和笔,尤其是对于链表和dp相关的题,可以画出来,不然抽象起来…紧张的时候可能会有纰漏。)
言归正传,此题显然算法简单或者中级题。傻瓜式的可选的方案有:
-
哈希。
遍历链表…哈希map统计每一个值出现的次数;将只出现一次的值,存入vector数组。恢复链表(这一步实际上很折腾)。 -
常规解法:建议画图抽象出来
分析:
1)凡事先特判! 先特例,再抽象一般。
此题中:考虑,头结点head为空或者head->next为空,则分别返回NULL和head即可。
2)一般:链表多于1个节点
由于链表头结点可能存在重复,并且链表有序,则重复值必然连续…即curr->val !=curr->next->val
成立时,curr->val
不重复,否则寻找下一个不等于curr->val
的节点。
我们可以使用一个哑巴节点(此题不必须),来记录不重复的节点。
用curr_num
记录当前节点的值:
- 当
curr->val !=curr->next->val
满足时,将该节点的值加入链表, - 否则寻找下一个值不等于curr_num的节点。
直到curr指针遍历到链表末端节点,此时curr->next==NULL
。
则最后一个节点未添加进去,此时判断其值是否等于curr_num即可,若不等,则加入。
以下为事后诸葛代码,欢迎批评斧正!
//
// Created by wbzhang on 2020/9/28.
//
#include <iostream>
#include <vector>
#include "../00-TopFrequency/helperList.h"
using namespace std;
class Solution {
public:
ListNode *deleteDuplicates(ListNode *head) {
if(!head) return NULL;
if(!head->next) return head; // 特判
// 哑巴节点
ListNode *dummyNode = new ListNode(-1);
ListNode *pre = dummyNode,*curr = head;
int curr_num = curr->val;
while(curr!=NULL && curr->next!=NULL)
{
curr_num = curr->val;
if(curr->next->val != curr_num){
ListNode* newNode = new ListNode(curr_num);
pre->next = newNode;
pre = pre->next;
// cout<<"once..."<<endl;
// printList(dummyNode->next);
// cout<<endl;
}
// 尋找下一個不同的值
while(curr->val == curr_num && curr->next!=NULL){
curr = curr->next;
}
}
// 最後一個節點無法覆蓋到
if(curr_num!=curr->val){
pre->next = curr;
}
// cout<<"once..."<<endl;
// printList(dummyNode->next);
// cout<<endl;
return dummyNode->next;
}
};
int main()
{
// 自選若干組測試用例如下:
// vector<int> nums = {1,2,3,3,4,4,5};
vector<int> nums = {1,2,2,3,3,4,4,5,5,5,5,5,5};
// vector<int> nums = {};
// vector<int> nums = {1};
// 构建链表
ListNode *head;
if(nums.size()>0){
head = new ListNode(nums[0] );
ListNode *curr = head;
for (int i = 1; i < nums.size(); ++i) {
ListNode *newNode = new ListNode( nums[i] );
curr->next = newNode;
curr = curr->next;
}
printList(head);
cout<<" ---" <<endl;
}else{
head = NULL;
}
Solution solu;
ListNode* ans = solu.deleteDuplicates(head);
cout<<"ans: "<<endl;
printList(ans);
}
附上自己写的打印链表的辅助函数:
//
// Created by wbzhang on 2020/9/18.
//
#ifndef ALGORITHMS_HELPERLIST_H
#define ALGORITHMS_HELPERLIST_H
#include <iostream>
using namespace std;
struct ListNode{
int val;
ListNode* next;
ListNode(int _val):val(_val){
this->next = NULL;
};
};
// 递归打印链表
void printList(ListNode* head)
{
if(head==NULL) return;
cout<<head->val<<" ";
printList(head->next);
}
// 反转打印链表
void rprintList(ListNode* head)
{
if(head==NULL) return;
rprintList(head->next);
cout<<head->val<<" ";
}
#endif //ALGORITHMS_HELPERLIST_H
此题为leetcode No.83
原题,中等难度。当场没做出来,只能证明我菜。
输了说什么都像是借口,好好学习吧还是。