1. 程式人生 > 其它 >力扣劍指Offer(九)

力扣劍指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);
    }
};