c语言--力扣中等题目(删除排序链表中的重复元素)讲解

题目如下:

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

示例 1:

输入:head = [1,2,3,3,4,4,5] 输出:[1,2,5]

示例 2:

输入:head = [1,1,1,2,3] 输出:[2,3]

提示:

链表中节点数目在范围 [0, 300] 内

-100 <= Node.val <= 100

题目数据保证链表已经按升序 排列

效果如下:
请添加图片描述

代码部分:

第一部分

结构体定义:

typedef struct Node {
int val;
struct Node* next;
}Node;
typedef Node* List;

代码部分:

List head, head1, tail;
Node* p,*p1;//p用来创建空节点,p1用来释放被删除节点的内存
p = (Node*)malloc(sizeof(struct Node));
int ch;
int nums=0;
head = p,head1=p;
tail = p;
p1 = p;
head->next = NULL;
printf("请输入链表内容");
while ((ch = getchar()) != '\n') {
    if (ch == ' ')
        continue;
    else {
        p = (Node*)malloc(sizeof(struct Node));
        p->val = ch - 48;
        tail->next = p;
        tail = p;
        tail->next = NULL;
    }
}
tail = head;
head1 = head1->next;//指向第一个节点

我们先进行内容的输入,因为题目的规定,所以我们这里采用升序输入。
之后让tail重新指向头节点,head1指向第一个储存值的节点。

第二部分

for (; head1->next != NULL;) {
    if (head1->val != nums) {
        nums = head1->val;
    }
    if(head1->next->val == nums) {
        p1 = head1;
        tail->next = head1->next;
        head1 = head1->next;
        free(p1);
        if (head1->next == NULL) {//判断是否会越界
            free(head1);
            tail->next = NULL;
            break;
        }
        else if (head1->next->val != nums) {
            p1 = head1;
            tail->next = head1->next;
            head1 = head1->next;
            continue;
        } 
        continue;//避免tail和head1指向不是我们预期的节点
    }
    tail = tail->next;//避免tail一直停留在当前节点
    head1 = head1->next;//避免head1一直停留在当前节点
}

我们先用一个if语句记录下第一个节点的值,之后又进行一次判断,如果下一个节点的值和当前节点的值相同,那么我们就进行删除当前节点的操作,在这里,我们又进行了一次判断,判断现在的head1是否是最后一个节点,如果是的话,就删除这个节点,并且结束循环,避免越界,如果不是,那么就进行删除操作,并且让head1指向下一个节点。

循环的后面部分,我们让tail指向下一个节点,也让head1指向下一个节点。

为什么呢,比如我们输入的是1 2 3,如果没有这两个语句,那么head1和tail就会一直停留在当前节点,有了这两个语句,那么我们的if语句内也要进行修改,所以我们才在if语句内加了continue。

第三部分

for (; head->next != NULL;) {
    head = head->next;
    printf("%d ", head->val);
}
return 0;  

这部分进行打印,打印完成后直接结束程序。

至此,讲解完毕。

(新人写作,有些地方可能讲解不清,请谅解)。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值