马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
示例1:
- <strong> 输入</strong>:[1, 2, 3, 3, 2, 1]
- <strong> 输出</strong>:[1, 2, 3]
复制代码 示例2:
- <strong> 输入</strong>:[1, 1, 1, 1, 2]
- <strong> 输出</strong>:[1, 2]
复制代码 提示:
- 链表长度在[0, 20000]范围内。
- 链表元素在[0, 20000]范围内。
进阶:
如果不得使用暂时缓冲区,该怎么解决?
这道题我一开始的思路新建一个链表,直接遍历判断链表是否存在当前遍历到的值,若未遍历到,则存入新的链表,若存在,则判断下一个值
leetcode代码
- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
- class Solution {
- public:
- ListNode* removeDuplicateNodes(ListNode* head) {
- // 如果链表为空,则直接返回nullptr,因为没有节点需要处理
- if(head == nullptr){
- return head;
- }
-
- // 声明一个哈希表(unordered_set),用于存储已经出现过的节点值
- // 初始时将头结点的值插入哈希表,因为头结点总是需要保留的(除非它是重复的,但这种情况在题目中未明确说明如何处理)
- unordered_set<int> occurred = {head->val};
-
- // pos指针用于遍历链表,初始时指向头结点
- ListNode* pos = head;
-
- // 遍历链表,直到pos的下一个节点为空(即链表末尾)
- while(pos->next != nullptr){
- // cur指针指向pos的下一个节点,即当前正在检查的节点
- ListNode* cur = pos->next;
-
- // 如果cur节点的值没有出现在哈希表中,说明它不是重复节点
- if(!occurred.count(cur->val)){
- // 将cur节点的值添加到哈希表中,表示该值已经出现过
- occurred.insert(cur->val);
- // 移动pos指针到下一个节点,继续检查
- pos = pos->next;
- }else{
- // 如果cur节点的值是重复的,则删除该节点
- // 通过将pos的next指针指向cur的next指针,实现跳过cur节点
- pos->next = pos->next->next;
- // 注意:这里不需要移动pos指针,因为pos的下一个节点(即原来的cur节点)已经被删除了
- }
- }
-
- // 注意:在遍历结束后,pos指针会指向链表的最后一个非重复节点
- // 由于链表末尾的next指针应该为nullptr,所以这里显式地将pos的next指针设置为nullptr
- // 这一步其实是多余的,因为在遍历过程中,如果链表末尾的节点不是重复的,pos最终会指向它,并且它的next已经是nullptr了
- // 但为了代码的清晰性和完整性,还是保留这一行代码
- pos->next = nullptr;
-
- // 返回处理后的链表头结点
- return head;
- }
- };
复制代码- /**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
-
- class Solution {
- public:
- /**
- * 移除链表中所有重复的节点,只保留原始节点链表中每个值第一次出现的节点。
- * @param head 链表的头节点
- * @return 移除重复节点后的链表的头节点
- */
- ListNode* removeDuplicateNodes(ListNode* head) {
- if (head == nullptr) {
- // 如果链表为空,则直接返回nullptr
- return nullptr;
- }
-
- ListNode* ob = head; // ob(outer block)用于遍历整个链表
- while (ob != nullptr) {
- ListNode* oc = ob; // oc(outer current)用于在ob指向的节点之后查找重复节点
- while (oc->next != nullptr) {
- // 如果发现oc的下一个节点的值与ob相同,则移除oc的下一个节点
- if (oc->next->val == ob->val) {
- oc->next = oc->next->next;
- } else {
- // 如果没有发现重复,则oc继续向后移动
- oc = oc->next;
- }
- }
- // 完成ob节点之后所有重复节点的移除后,ob向后移动
- ob = ob->next;
- }
- return head; // 返回修改后的链表的头节点
- }
- };
复制代码 因为问到不使用暂时缓冲区,因此采用下面这种用时间换空间的做法。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |