链表简单例题

1.给你一个链表的头节点 head ,判断链表中是否有环。

bool hasCycle(struct ListNode *head) {
    //快慢结点法
    //定义两个结点,一个快结点,一个慢结点,所谓快结点就是一次跳两个,慢结点按部就班一次跳一个
    //若链表有环则快结点一定先进入在环中旋转,慢结点后进入,当两个结点相遇时说明存在环
    //若快结点直接跑到NULL了说明没有环
    if(head == NULL || head->next == NULL)
    {
        return 0;
    }
    struct ListNode *fast = head->next;       //定义细节:fast的开始为head->next,而不是head
    struct ListNode *slow = head;             //防止后面判断时直接跳出循环
    while(slow != fast)
    {
        if(fast == NULL || fast->next == NULL)
        {
            return 0;
        }
        slow = slow->next;
        fast = fast->next->next;
    }
    return 1;
}
  1. 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
struct ListNode* reverseList(struct ListNode* head){

    //
    struct ListNode *cur = head;        //当前指向的结点
    struct ListNode *temp;              //当前结点的下一结点
    struct ListNode *pre = NULL;        //当前结点的上一结点

    //总体过程:temp首先存储cur的下一个结点,之后cur->指向pre结点,然后到达结点更新阶段
             //pre更新为cur,而更新为temp,更新的顺序不可以颠倒
    while(cur)
    {
        temp = cur->next;
        cur->next = pre;
        pre = cur;
        cur = temp;
    }
    return pre;
}

3.二进制链表整数转换
给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。请你返回该链表所表示数字的 十进制值 。

int getDecimalValue(struct ListNode* head){
    //思路:此题就是模拟的数制转换,ans = ans * 2 + temp->val这个公式是核心
         //从最高位开始每进入一个新结点就*阶码,最后到达最后的结点之后,ans加上链表中最后一位也就是个位的数值
         //刚好模拟了整个过程
    struct ListNode *temp = head;
    int ans = 0;
    while(temp)
    {
        ans = ans * 2 + temp->val;
        temp = temp->next;
    }
    return  ans;
}

4.合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

尤其注意该题的递归思路

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){

    //递归思路
    if(list1 == NULL)			//两个递归的基线情况
    {
        return list2;
    }
    if(list2 == NULL)
    {
        return list1;
    }
    
    if(list1->val < list2->val)
    {
        list1->next = mergeTwoLists(list1->next,list2);
        return list1;
    }
    else 
    {
        list2->next = mergeTwoLists(list1,list2->next);
        return list2;
    }


    //迭代思路
    struct ListNode hair;
    hair.next = list1;
    struct ListNode *cur = &hair;
    while(list1 != NULL && list2 !=NULL )
    {
        if(list1->val > list2->val)
        {
            cur->next = list2;
            list2 = list2->next;
        }
        else 
        {
            cur->next = list1;
            list1 = list1->next;
        }
        cur = cur->next;
    }
   cur->next = list1 == NULL ? list2 : list1;
   return hair.next;
}

5.删除排序链表中的重复元素
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。

同样注意递归的思路

struct ListNode* deleteDuplicates(struct ListNode* head) {
    //思路:注意审题事先给定的链表已经是排列好的了,所以每个相同的值都会排列在一起的
          //只需要一个中间指针的循环就可以解决这个问题了。
          //链表中的数据没有事先排列好,可以使用两个指针来模拟双层循环来解决
    //1.指针法
    if(head == NULL)
    {
        return head;
    }
    struct ListNode *temp = head;
    while(temp->next)
    {
        if(temp->val == temp->next->val)
        {
            temp->next = temp->next->next;
        }
        else 
        {
            temp = temp->next;
        }
    }
    return head;

`   //2.递归法
    if(head == NULL || head->next == NULL)          //基线情况
    {
        return head;            
    }
    if(head->val != head->next->val)                //当head与后面结点值不同的时候保留head,让head->next进入递归
    {
        head->next = deleteDuplicates(head->next);
    }
    else                                            //相同的时候
    {
        struct ListNode *move;
        move = head->next;
        while(move->next && head->val == move->next->val)   //move指针负责查找最后一个与head值相同的结点
        {
            move = move->next;
        }
        return deleteDuplicates(move);             //返回该结点,意味着该节点之前的值相同的结点都被删除
                                                   //只保留了最后一个结点
    }
    return head;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值