赞
踩
题目描述 链接:倒数第K个节点
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。
注意:本题相对原题稍作改动
示例:
输入: 1->2->3->4->5 和 k = 2
输出: 4
说明:
给定的 k 保证是有效的。
这道题我们可以用快慢指针的方式来解决,这里的快慢指针不是fast走两步,或者slow走一步的那种快慢指针,而是快指针先走K步,走完之后在让慢指针走,为什么这样做,因为我们这样做先让两个指针拉开K步的差距,让两个指针同时走,等到快指针走完链表最后,走完链表,最后slow就距离链表尾部就差k个距离,因为他们两个之间的距离是恒等不变的。
下面画图来看看
下面是代码
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ typedef struct ListNode ListNode; int kthToLast(struct ListNode* head, int k){ ListNode* fast = head; ListNode* slow = head; for(int i = 0;i<k;i++) { fast = fast->next; } while(fast != NULL) { fast = fast->next; slow = slow->next; } return slow->val; }
链表的回文
描述
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
返回:true
这道题我们的思路是先找到链表的中点,在反转链表中间节点后面的部分,最后让两个链表一个从中间节点开始,另一个从头节点开始,同时往后面遍历,当从中间节点往后遍历为空的时候就结束。这里链表分奇数和偶数个的情况,我们这里偶数恰好满足题目要求,返回后一个节点。
下面我们画图来看看
我们链表的反转用的是,改变指针的指向来反转的,下面是思路
代码
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) {} };*/ struct ListNode* find_mid(struct ListNode* head) { struct ListNode* fast = head; struct ListNode* slow = head; while(fast->next !=NULL && fast) { fast = fast->next->next; slow = slow->next; } return slow; } struct ListNode* revse_mid(struct ListNode* mid) { struct ListNode* p1 = NULL; struct ListNode* p2 = mid; struct ListNode* p3 = p2->next; while(p2) { p2->next = p1; p1 = p2; p2 = p3; if(p3 != NULL) { p3 = p3->next; } } return p1; } class PalindromeList { public: bool chkPalindrome(ListNode* A) { struct ListNode* mid = find_mid(A); struct ListNode* rervse = revse_mid(mid); struct ListNode* pcur1 = rervse; while(A != NULL && pcur1 != NULL) { if(A->val != pcur1->val) { return false; } A = A->next; pcur1 = pcur1->next; } return true; } };
相交链表
题目描述;
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
图示两个链表在节点 c1 开始相交:
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
自定义评测:
评测系统 的输入如下(你设计的程序 不适用 此输入):
intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
listA - 第一个链表
listB - 第二个链表
skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数
评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。
这道题我们采用的方法是,先判断链表中,那个链表是长链表,哪个链表是短链表,在拿长链表的节点数去减短链表的节点数,获得差值,最后让长链表先走差值,走完之后让短链表和长链表一起走,他们相遇的地方就是交点,如果没有就是没有交点
下面是代码
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ typedef struct ListNode listnode; struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) { listnode* pcur1 = headA; listnode* pcur2 = headB; int leng1 = 0; int leng2 = 0; while(pcur1 != NULL) { pcur1 = pcur1->next; leng1++; } while(pcur2 != NULL) { pcur2 = pcur2->next; leng2++; } if(pcur1 != pcur2) { return NULL; } listnode* longlist = headA; listnode* shortlist = headB; int gap = abs(leng1 - leng2);//取绝对值,长度不可能是负数,假设法第一个链表是长链表,第二个是短链表 if(leng1>leng2) { longlist = headA; shortlist = headB; } else { longlist = headB; shortlist = headA; } while(gap--) { longlist = longlist->next; } while(longlist != shortlist) { longlist = longlist->next; shortlist = shortlist->next; } return longlist; }
以上就是本文的内容了,如果有什么错误欢迎指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。