1.验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。节点的右子树只包含大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-binary-search-tree
思路一:二叉搜索树中序遍历是一个递增序列。
/** * 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 isValidBST(TreeNode* root) { if(root == NULL) return true; //vector<int> t; dfs(root); for(int i =0;i < t.size() - 1;i++){ if(t[i + 1] <= t[i]) return false; } return true; } void dfs(TreeNode* root){ if(root -> left) dfs(root->left); t.push_back(root -> val); if(root -> right) dfs(root->right); } private: vector<int> t; };
思路二:递归:设置一个区间,首先根节点的值应位于无穷大与无穷小之间,然后依次遍历左子树与右子树,因为左子树的值应都小于根节点,因此上界是根节点的值,而右子树下界是根节点的值。
class Solution { public: bool helper(TreeNode* root, long long lower, long long upper) { if (root == nullptr) return true; if (root -> val <= lower || root -> val >= upper) return false; return helper(root -> left, lower, root -> val) && helper(root -> right, root -> val, upper); } bool isValidBST(TreeNode* root) { return helper(root, LONG_MIN, LONG_MAX); } };
2.链表中倒数第K个节点
思路:双指针,先让第一个指针从头走k步,然后第二个指针与第一个指针一同开始走,当第一个指针z时,第二个指针就到了倒数第k个节点。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if(pListHead==nullptr||k==0) return nullptr; ListNode* p1=pListHead; ListNode* p2=nullptr; for(int i=0;i<k-1;i++) { if(p1->next!=nullptr) p1=p1->next; else return nullptr;//k大于链表的长度 } p2=pListHead;//只有合法时才将第二个指针指向头结点 while(p1->next!=nullptr) { p2=p2->next; p1=p1->next; } return p2; } };
3.反转链表
输入一个链表,将其反转,并返回新链表的表头。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* ReverseList(ListNode* pHead) { if(pHead==nullptr||pHead->next==nullptr) return pHead;//边界情况 ListNode *pReversedHead=nullptr;//用于记录最后一个节点 ListNode *pNode=pHead;//当前节点 ListNode *pPrev=nullptr;//当前节点的前一个节点 while(pNode!=nullptr) { ListNode* pNext=pNode->next; if(pNext==nullptr) pReversedHead=pNode;//如果pNode到达尾结点,令此节点等于pNode pNode->next=pPrev; pPrev=pNode; pNode=pNext; //反转操作 } return pReversedHead; } };
4.合并两个排序的链表
思路:递归思路和循环思路。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* Merge(ListNode* pHead1, ListNode* pHead2) { if(pHead1==nullptr) return pHead2; if(pHead2==nullptr) return pHead1; ListNode* newHead=nullptr; if(pHead1->val<pHead2->val) { newHead=pHead1; newHead->next=Merge(pHead1->next,pHead2); } else if(pHead1->val>=pHead2->val) { newHead=pHead2; newHead->next=Merge(pHead1,pHead2->next); } return newHead; } };