LeetCode-鏈表相關面試題(一)

一,相交鏈表(160題)

1 題目要求:編寫一個程序,找到兩個單鏈表相交的起始節點。

2 題目描述

傳入兩個鏈表,判斷是否相交,如果相交,返回相交位置的結點。例如本例返回c1結點,如果不相交,返回NULL

例如:該例子相交,所以返回 8 這個結點

例如:該例子,兩個鏈表不相交,返回NULL

3 分析題目實現過程 :1,首先求兩條鏈表的長度,

2,求出兩條鏈表長度的差size,

3,定義兩個指針,分別指向兩個鏈表的頭結點,

4,讓長鏈表的指針先往後走 size步,

5,讓兩個指針同時往後走,比較每個結點,判斷結點是否相同,

6,如過結點相同,就返回該結點,

7,否則,返回NULL。

4 代碼實現 : 

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
	struct ListNode* pA1 = headA, *pA2 = headA;
	struct ListNode* pB1 = headB, *pB2 = headB;
	int lengthA = 0;
	int lengthB = 0;
	while (pA1 != NULL) {
		lengthA++;
		pA1 = pA1->next;
	}
	while (pB1 != NULL) {
		lengthB++;
		pB1 = pB1->next;
	}
	int size = (lengthA>lengthB) ? (lengthA - lengthB) : (lengthB - lengthA);
	if (lengthA >= lengthB) {
		for (int i = 0; i<size; i++) {
			pA2 = (pA2->next);
		}
		while (pA2 != NULL && pB2 != NULL) {
			if (pA2 == pB2) {
				return pA2;
			}
			pA2 = pA2->next;
			pB2 = pB2->next;
		}
		return NULL;
	}
	else {
		for (int i = 0; i < size; i++) {
			pB2 = (pB2->next);
		}
		while (pB2 != NULL &&pA2 != NULL) {
			if (pB2 == pA2) {
				return pB2;
			}
			pA2 = pA2->next;
			pB2 = pB2->next;
		}
		return NULL;
	}
}

二,刪除鏈表元素(203題)

題目要求 : 刪除鏈表中等於給定值 val 的所有節點。

題目描述 :

   

   傳入一個鏈表,在該函數中操作之後,刪除所有指定結點,然後返回鏈表,例如:該例子,傳入第一個結點的地址,刪除val = 6的結點之後,返回指向第一個結點的指針。

分析題目實現過程:1,首先判斷傳入的鏈表是否爲空,如果爲空,返回NULL,

2,如果不爲空,開始從第二個結點遍歷,比較結點的值是否等於val,如過等於,刪除結點,否則,繼續循環,

      這塊注意如果刪除結點,刪除完結點之後一定要在 cur = cur->next 之前繼續一次循環,否則少比較了一個結點。

3,判斷第一個結點的值是否等於 val ,如果等於,保存第二個結點,刪除第一個結點,返回第二個結點的地址,

4,否則返回第一個結點的地址。

代碼實現

struct ListNode* removeElements(struct ListNode* head, int val) {
	if (head == NULL) {
		return NULL;
	}
	struct ListNode* cur = head;
	while (cur->next != NULL) {
		struct ListNode* next = cur->next;
		if (cur->next->val == val) {
			cur->next = cur->next->next;
			free(next);
			continue;
		}
		cur = cur->next;
	}
	if (head->val == val) {
		struct ListNode* next = head->next;
		free(head);
		return next;
	}
	return head;
}

三,刪除鏈表中的結點(237題)

題目要求:請編寫一個函數,使其可以刪除某個鏈表中給定的(非末尾)節點,你將只被給定要求被刪除的節點。

題目描述

傳入一個鏈表。調用了我們的函數之後,刪除了node結點。

分析題目實現過程:因爲無法知道node的上一個結點,所以只能將node後面結點的值賦給node結點,然後刪除node後面的結點。

代碼實現

void deleteNode(struct ListNode* node) {
	struct ListNode* next = node->next;
	node->val = node->next->val;
	node->next = node->next->next;
	free(next);
}

四,反轉鏈表(206題)

題目要求  : 反轉一個單鏈表.

題目描述  : 

  

傳入一個鏈表。將鏈表逆置之後返回。

分析題目實現過程 :定義兩個指針,一個 cur 指向鏈表頭結點,一個 prev 設置爲空,如果 cur 不爲空,就記錄下 cur 後面的結

點爲 next,將 cur 的 next 置爲 prev 然後更改 cur 爲 next ,prev 改爲 cur ,然後繼續循環,直到條件不滿足(cur == NULL),

返回 prev 的地址。

代碼實現 : 

struct ListNode* reverseList(struct ListNode* head) {
	struct ListNode* cur = head;
	struct ListNode* prev = NULL;
	while (cur != NULL) {
		struct ListNode* next = cur->next;
		cur->next = prev;
		prev = cur;
		cur = next;
	}
	return prev;
}

五,分隔鏈表(86題)

題目要求

給定一個鏈表和一個特定值 x,對鏈表進行分隔,使得所有小於 x 的節點都在大於或等於 x 的節點之前。應當保留兩個分區中每個節點的初始相對位置。

題目描述

傳入一個鏈表,傳入一個參數x,拿鏈表中的每一個結點的值和x做比較,如果小於x,就依次按照原鏈表順序放在大於等於x 的前面。

分析題目實現過程:1,首先創建兩個的結點 t1, t2,用來作爲保存小於 和 大於等於 x值結點的新鏈表的頭結點。

2,分別定義兩個指針變量temp1,temp2用來操作t1,t2,

3,用原鏈表的每一個結點的值和 x 做比較,小於x 的話,就將結點放在t1後面,否則,放在t2 後面,

4,原鏈表比較完之後,把連個鏈表連接起來,釋放掉申請的兩個結點的內存。返回新的鏈表。

代碼實現

struct ListNode* partition(struct ListNode* head, int x) {
	if (head == NULL) {
		return NULL;
	}
	struct ListNode* t1 = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* t2 = (struct ListNode*)malloc(sizeof(struct ListNode));
	struct ListNode* temp1 = t1;
	struct ListNode* temp2 = t2;
	while (head != NULL) {
		if (head->val < x) {
			temp1->next = head;
			temp1 = temp1->next;
		}
		else {
			temp2->next = head;
			temp2 = temp2->next;
		}
		head = head->next;
	}
	temp2->next = NULL;
	temp1->next = t2->next;
	temp1 = t1->next;
	free(t1);
	free(t2);
	return temp1;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章