力扣剑指Offer(九)

1、反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

限制:

0 <= 节点个数 <= 5000

方法一:迭代

/**
 * 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) {
        ListNode* pre=NULL;
        ListNode* p=head;
        while(p){
           ListNode* q=p->next;
           p->next=pre;
           pre=p;
           p=q;
        }
        return pre;
    }

};

方法二:递归

/**
 * 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) {
        if(!head||!head->next)
            return head;
        ListNode* newHead = reverseList(head->next);
        head->next->next=head;
        head->next=NULL;
        return newHead;
    }
};

2、和为s的两个数字

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

示例 1:

输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]

示例 2:

输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]

限制:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^6

方法一:哈希表

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> res;
        unordered_map<int,int> mp;
        for(int i=0;i<nums.size();i++){
            mp[nums[i]]++;
        }
        for(int i=0;i<nums.size();i++){
            if(mp[nums[i]]&&mp[target-nums[i]]){
                res.push_back(nums[i]);
                res.push_back(target-nums[i]);
                break;
            }
        }
        return res;
    }
};	

方法二:双指针

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int i=0;
        int j=nums.size()-1;
        while(i<j){
            if((nums[i]+nums[j])==target) {
                return vector<int>{nums[i],nums[j]};
            }
            else if((nums[i]+nums[j])<target) i++;
            else j--;
        }
        return vector<int>();
    }
};

3、树的子结构

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)

B是A的子结构, 即 A中有出现和B相同的结构和节点值。

例如:
给定的树 A:

3
/
4 5
/
1 2

给定的树 B:

4
/
1

返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

示例 1:

输入:A = [1,2,3], B = [3,1]
输出:false

示例 2:

输入:A = [3,4,5,1,2], B = [4,1]
输出:true

限制:

0 <= 节点个数 <= 10000

方法:递归

/**
 * 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) {
        return (A!=NULL&&B!=NULL)&&(recur(A,B)||isSubStructure(A->left,B)||isSubStructure(A->right,B));
    }
    bool recur(TreeNode* A, TreeNode* B) {
        if(B==NULL)
            return true;
        if(A==NULL||A->val!=B->val)
            return false;
        return recur(A->left,B->left)&&recur(A->right,B->right);
    }
};
posted @ 2021-06-23 15:13  Barrymeng  阅读(43)  评论(0)    收藏  举报