LeetCode刷题总结(C语言版)_链表类

编程总结

每每刷完一道题后,其思想和精妙之处没有地方记录,本篇博客用以记录刷题过程中的遇到的算法和技巧

206)反转链表
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

下图一到图二进行了四个步骤的变化:
LeetCode刷题总结(C语言版)_链表类_第1张图片LeetCode刷题总结(C语言版)_链表类_第2张图片

struct ListNode* reverseList(struct ListNode* head){
    
	ListNode *pre = NULL; //需要指向前一个元素的指针
	ListNode *cur = head;
	
    while (cur != NULL) // cur 移动到NULL,此时pre就是新链表的第一个节点
    {
		ListNode *next = cur->next; // 保存 cur 的 next 节点
        cur->next = pre;  // cur新的next指向pre,也就是节点反向,同时,此时cur之前的next就断了,也是为什么要先保留cur->next 的原因  
        pre = cur;        // 平移pre节点
        cur = next;       // 平移cur节点
        // 平移后,继续之前的操作,先保留next,然后反向cur->next,然后平移
    }
    return pre; // 新链表的头结点,pre
}

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

struct ListNode *mergeTwoLists(struct ListNode *l1, struct ListNode *l2){

    int length_l1 = 0;
    int length_l2 = 0;
    struct ListNode *head = NULL;
    struct ListNode *res  = NULL;
    struct ListNode *l1_t  = l1;
    struct ListNode *l2_t  = l2;

    if (l1 == NULL && l2 == NULL) {
        return NULL;
    }
    // 1.计算 l1 l2 的length
    while(l1_t != NULL) {
        l1_t = l1_t->next;
        length_l1++;
    }
    while(l2_t != NULL) {
        l2_t = l2_t->next;
        length_l2++;
    }
    // 新建一个新的链表
    head = (struct ListNode *)malloc((length_l1 + length_l2)*sizeof(struct ListNode ));
    res  = head;

    while (l1 != NULL || l2 != NULL) {
        // 特殊情况处理
        if (l1 == NULL) {
            head->next = l2;
            l2 = l2->next;
            head = head->next;
        }
        else if (l2 == NULL) {
            head->next = l1;
            l1 = l1->next;
            head = head->next;
        }
        // 2.哪个小赋值到新的链表里去
        else if (l1 != NULL && l2 != NULL) {
            if (l1->val <= l2->val) {
                head->next = l1;
                head = head->next;
                l1   = l1->next;
            } else {
                head->next = l2;
                head = head->next;
                l2   = l2->next;
            }
        }
    }
    return res->next;
}

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

	// 注意是 malloc(sizeof(struct ListNode));
	// 不是 mallocl(sizeof(struct ListNode *));
	// 区别是 malloc一个指针指向 大小为 ListNode
	struct ListNode *head = NULL;
	head = (struct ListNode *)malloc(sizeof(struct ListNode));
  1. 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
struct ListNode *deleteDuplicates(struct ListNode *head)
{
	struct ListNode *cur = head;
	int value = 0;
	int value_next = 0;
	
	while (cur != NULL && cur->next != NULL) {
		value = cur->val;	
		value_next = cur->next->val;
		if (value == value_next) {
			cur->next = cur->next->next;
		} else {
			cur = cur->next;
		}
	}

	return head;
}

你可能感兴趣的:(匠心)