NO56、删除链表中的重复结点(不保留重复点,很好的题目)

  • Post author:
  • Post category:其他




56、

删除链表中的重复结点

,不保留重复点 很好的题目

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

示例1

输入

{1,2,3,3,4,4,5}

返回值

{1,2,5}


1、真的是超级笨,我服了,调试了很多遍才通过的

大概思想:采用vector保存链表中的不重复元素,然后将链表从表头开始挨个对比,一样就将当前结点保存下来,然后index++,不一样就继续向下遍历,注意边界条件。

  ListNode* deleteDuplication(ListNode* pHead)
    {
	if (pHead == nullptr || pHead->next == nullptr) return pHead;
	ListNode* node = (ListNode*)malloc(sizeof(struct ListNode));
	node = pHead;
	vector<int> result;
	result.push_back(node->val);
	node = node->next;
	while (node != nullptr) {
		if (result.size()!=0 && result.back() == node->val) {
			while (node!=nullptr && result.back() == node->val) {
				node = node->next;
			}
			result.pop_back();
		}
		else if (result.size() == 0 || (result.size()!=0 && result.back()!=node->val))
		{
			result.push_back(node->val);
			node = node->next;
		}	
		else
			node = node->next;
	}

	if (result.size() == 0) {
		return nullptr;
	}
	node = pHead;
	int index = 0;
	int len = result.size();
	ListNode* resultNode = (ListNode*)malloc(sizeof(struct ListNode));
	while (node != nullptr) {
		if (index<len && node->val == result[index]) {
			index++;
			resultNode = node;
			break;
			
		} node = node->next;
	}
	pHead = resultNode;
	while (node != nullptr) {
		if (index < len && node->val == result[index]) {
			index++;
			pHead->next = node;
			pHead = pHead->next;

		} node = node->next;
	}
    pHead->next = nullptr;//最后要设置尾点结束
	return resultNode;
    }


2、别人的思路和方法,三指针法,取到原来指针的前一个指针
  1. 首先添加一个头节点,以方便碰到第一个,第二个节点就相同的情况

​ 2.设置 pre ,cur指针, pre指针指向当前确定不重复的那个节点,而last指针相当于工作指针,一直往后面搜索。

if (pHead == nullptr || pHead->next == nullptr) { return pHead; }
	ListNode *Head = (ListNode*)malloc(sizeof(struct ListNode));
	ListNode* pre = (ListNode*)malloc(sizeof(struct ListNode));
	ListNode* cur = (ListNode*)malloc(sizeof(struct ListNode));
	Head->next = pHead;
	pre = Head; //pre相当于原来节点的前一个节点
	cur = Head->next; //cur相当于 原来的节点
	while (cur != nullptr) {
		if (cur->next != nullptr && cur->val == cur->next->val) {
			// 找到最后的一个相同节点
			while (cur->next != nullptr && cur->val == cur->next->val) {
				cur = cur->next;
			}
			pre->next = cur->next; //这里等于cur->next真的很棒
			cur = cur->next;
		}
		else {
			pre = pre->next;
			cur = cur->next;
		}
	}
	return Head->next;





二刷:


1、三指针法,可以将元素开辟到栈上
    ListNode* deleteDuplication(ListNode* pHead)
    {

        if(pHead == nullptr || pHead->next == nullptr) return pHead;
        ListNode dummpyHead(0);
        dummpyHead.next = pHead;
        ListNode *pre = &dummpyHead;
        ListNode *cur = dummpyHead.next;//cur是真正工作的节点
        while(cur != nullptr){
          if(cur->next != nullptr && cur->val == cur->next->val){
              while(cur->next != nullptr && cur->val == cur->next->val)
              {
                  cur = cur->next;
              }
              pre->next = cur->next;//这里还不要马上把 pre 赋值过来
              cur = cur->next;
          }else{
              pre = pre->next;
              cur = cur->next;
          }
         

        }
        return dummpyHead.next;
    }


变种:删除链表中的重复结点,保留一个重复点

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->3->4->5

    ListNode* deleteDuplication(ListNode* pHead)
    {
	if (pHead == nullptr) return nullptr;
	ListNode* node = (ListNode*)malloc(sizeof(struct ListNode));
	node = pHead;
	while (node != nullptr) {

		if (node->next!=nullptr && node->val == node->next->val) {//这里千万要判断node->next也不为空才可以
			while (node->next != nullptr && node->val == node->next->val) {
				node->next = node->next->next;
			}
		}
		node = node->next;
	}
	return pHead;
    }


另一种写法
ListNode* deleteDuplication(ListNode* pHead)
{

	if (pHead == nullptr || pHead->next == nullptr) return pHead;
	ListNode dummpyHead(0);
	dummpyHead.next = pHead;
	ListNode* pre = &dummpyHead;
	ListNode* cur = dummpyHead.next;
	while (cur != nullptr) {
		if (cur->next != nullptr && cur->val == cur->next->val) {
			while (cur->next != nullptr && cur->val == cur->next->val)
			{
				cur = cur->next;
			}
			pre->next = cur;
			pre = pre->next;
			cur = cur->next;
		}
		else {
			pre = pre->next;
			cur = cur->next;
		}


	}
	return dummpyHead.next;
}


美女帅哥们如果觉得写的还行,有点用的话麻烦点个赞或者留个言支持一下阿秀~

如果觉得狗屁不通,直接留言开喷就完事了。



需要该笔记PDF版本的去个人公众号【拓跋阿秀】下回复“阿秀剑指offer笔记”即可。



版权声明:本文为songhao19原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。