面试题22:链表中倒数第k个节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
/*
思路:使用双指针法,一开始首尾指针均在头节点,尾指针先向后移动k个节点(注意节点不足k个的情况),然后首尾指针同时后移,直到尾指针到链表尾部。
*/
if(head == NULL)
return head;
ListNode* tail = head;
while(k >= 1 && tail != NULL){
tail = tail->next;
k--;
}
if(k != 0) // 如果超过了最大长度
return head;
while(tail != NULL){
head = head->next;
tail = tail->next;
}
return head;
}
};
面试题23:链表中环的入口节点
面试题24:反转链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
/*
思路:设一个新头节点newHead,保存已经反转好的部分链表,对于一个新的节点,先保存好它的next,然后将它加到newHead的前面,最后在恢复它的next,不断后移,直到链表末尾。
*/
if(head == NULL)
return NULL;
ListNode* nextCopy, *newHead = NULL;
while(head != NULL){
nextCopy = head->next;
head->next = newHead;
newHead = head;
head = nextCopy;
}
return newHead;
}
};
面试题25:合并两个排序的链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
/*
思路:每次查看两个链表的头节点,如果有链表已经空了则直接将另一个链表续在尾部,否则比较大小。
*/
ListNode* newHead = new ListNode(0);
ListNode* newHeadCopy = newHead;
while(l1 != NULL || l2 != NULL){
if(l1 == NULL){
newHead->next = l2;
l2 = NULL;
}
else if(l2 == NULL){
newHead->next = l1;
l1 = NULL;
}
else if(l1->val < l2->val){
newHead->next = l1;
l1 = l1->next;
newHead = newHead->next;
}
else{
newHead->next = l2;
l2 = l2->next;
newHead = newHead->next;
}
}
ListNode* ans = newHeadCopy->next;
delete newHeadCopy;
return ans;
}
};
面试题26:树的子结构
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
/*
思路:在A中找子结构B,如果B为空则直接返回真,如果A的根节点与B的根节点取值相同,则继续匹配A和B的左右子树是否是子结构关系,如果根节点取值不同则以A的左右子节点为根节点继续和最原始的B子树进行子结构匹配。
*/
if(B == NULL)
return false;
return helper(A, B, B);
}
bool helper(TreeNode* A, TreeNode* B, TreeNode* oriB){
if(B == NULL)
return true;
bool temp = false;
if(A != NULL){
if(A->val == B->val)
temp = helper(A->left, B->left, oriB) && helper(A->right, B->right, oriB);
return temp || helper(A->left, oriB, oriB) || helper(A->right, oriB, oriB);
}
return false;
}
};