leetcode_1_22-鏈表中倒數第k個節點

個人目標:考研,同時注重算法能力。
開始日期:2020/2/29
水平:菜的一批
刷題目的:爲複試做準備,和找工作。
學習引路:
資源:
https://space.bilibili.com/300173531?spm_id_from=333.788.b_765f7570696e666f.2
leetcode
公衆號:labuladong
B站:花花醬

方法論:
(若是着急着工作)
1.時間規劃(集中式大量刷題 保持題感 養成刷題習慣)
2.按照類型去刷題(數據類型 算法) 網站頁面旁邊有篩選功能 up🐷置頂了刷題目錄
3.不能死記硬背 要理解題目套路舉一反三(這點很重要!)
4.對於新手來說 看答案是可以的(新手不一定能想出來最優解)
5.用筆記本 ipad學習(Goodnotes)
6.利用網上資源 搜索題解視頻(微信公衆號labuladong)油管和B站的在置頂鏈接上
7.刷題刷三遍原則:1.題目到手,5分鐘思考,沒有思路就看答案。2.有思路,不看答案一道題不要寫超過60分鐘。3.重刷要能夠在20分鐘內解決。4.多看人家的寫法。取其精華。在這裏插入圖片描述

1.題目:

在這裏插入圖片描述

2.代碼以及解題思路

code_1:
無從下手,不知道鏈表創建,參數都是不用寫的。後來查了資料才知道只用在已有模板內寫就夠了。
解題思路:
1.尾插法創建列表
2.算出列表的長度-k,算出指針要停留的位置
3.然後輸出後面鏈表
總結:第一次,不瞭解,c的知識也忘的差不多。

1.創建

/**Definition for singly-linked list. **/

struct ListNode {
     int val;
     struct ListNode *next;
};

struct ListNode* getKthFromEnd(struct ListNode* head, int k){
    int list_count = 0
    int list_print_begin = 0
    int *q = head
    while(head->next != NULL)
    {
        head = head->next;
        list_count ++;
    }
    list_count += 1;
    list_print_begin = list_count - k
    head = q
    
    for(int i = 0; i < list_print_begin; i++ )
    {
        head = head->next;
    }
    while(1)
    {   
        printf("%d", head->data)
        if(head->next == NULL)
        {   
            break;
        }
        head = head->next;
    }


} 


void main()
{   
    int *head_A 
    int key = 0;
    int a[5] = {0}
    for(i = 0; i<5; i++)
        scanf("d%", &a[i])
    head_A = creatlistA(ListNode *&A, a[], 5)
    printf("請輸入一個數:")
    scanf("%d", &key)
    getKthFromEnd(head_A, key)

}



void creatlistA(ListNode *&A, int a[], int n)
{   
    ListNode *s, *r;
    int i;
    A = (ListNode *)malloc(sizeof(ListNode));
    A -> = NULL;
    r = A;
    for(i = 0; i < n; ++i)
    {
        s = (ListNode*)malloc(sizeof(ListNode));
        s->data = a[i];
        r->next = s;
        r = r->next;
    }
    r->next = NULL;
    return A;
}

code_2
方法:雙指針

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* getKthFromEnd(struct ListNode* head, int k){
    struct ListNode* p_fast = head;
    struct ListNode* p_slow = head;
    while(k--)
    {
        p_fast = p_fast->next;
    }

    while(p_fast != NULL)
    {
        p_fast = p_fast->next;
        p_slow = p_slow->next;
    }
    return p_slow;
}

要點:
假設五個元素的鏈表,k=2
快指針先走2步,然後兩個指針同時走,當快指針剛走出鏈表,其實就是走了5步,而5-2就是慢指針要走的步數,也是定位點。然後輸出鏈表。

code_3
雙指針法:python實現

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        # fast_p = ListNode(1)
        # slow_p = ListNode(2)
        fast_p = slow_p = head

        while k:
            fast_p = fast_p.next
            k -= 1
        while fast_p is not None:
            fast_p = fast_p.next
            slow_p = slow_p.next
        
        return slow_p

3.總結

在這裏插入圖片描述
1.用python寫同樣的這種偏向於底層操作,發現各方面都不敵c這種編譯性語言。難怪有一些python的包是用c寫的。
2.方法很巧妙,要多刷題
當指針->next 已經爲空,再進行p = p ->next時候 p 指針 = NULL,
而且p指針已經沒有數據域和next指針域了。

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