首页 > 代码库 > 剑指offer(36-40)编程题

剑指offer(36-40)编程题

  • 两个链表的第一个公共结点
  • 数字在排序数组中出现的次数
  • 二叉树的深度
  • 平衡二叉树
  • 数组中只出现一次的数字

36.输入两个链表,找出它们的第一个公共结点。

 1 class Solution1 {
 2 public:
 3     ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
 4         ListNode* p = pHead1;
 5         ListNode* q = pHead2;
 6         unordered_set<ListNode*> us;
 7         while (p) {
 8             us.insert(p);
 9             p = p->next;
10         }
11         while (q) {
12             if (us.find(q) != us.end()) {
13                 return q;
14             }
15             q = q->next;
16         }
17         return nullptr;
18     }
19 };
20 
21 class Solution2 {
22 public:
23     ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
24         ListNode* p = pHead1;
25         ListNode* q = pHead2;
27         int n1 = 0, n2 = 0;
28         while (p) {
29             n1++;
30             p = p->next;
31         }
32         while (q) {
33             n2++;
34             q = q->next;
35         }
37         p = pHead1;
38         q = pHead2;
39         if (n1 > n2) {
40             for (int i = 0; i < n1 - n2; i++) {
41                 p = p->next;
42             }
43         } else {
44             for (int i = 0; i < n2 - n1; i++) {
45                 q = q->next;
46             }
47         }
49         while (p) {
50             if (p == q)
51                 return p;
52             else {
53                 p = p->next;
54                 q = q->next;
55                 break;
56             }
57         }
58         return p;
59     }
60 };

 37.统计一个数字在排序数组中出现的次数。

class Solution {
private:
     //not found ,return -1
    int getFirstK(vector<int>& data, int left, int right, int k) {
        if (left > right) return -1;
        int mid = left + (right - left) / 2;
        if (data[mid] > k) return getFirstK(data, left, mid - 1, k);
        else if (data[mid] < k) return getFirstK(data, mid + 1, right, k);
        else if (data[mid] == k && data[mid - 1] == k)
            return getFirstK(data, left, mid - 1, k);
        else return mid;
    }
     //not found ,return -1
    int getLastK(vector<int>&data,int left,int right,int k){
        if(left > right) return -1;
        int mid = left + (right-left)/2;
        if(data[mid] < k) return getLastK(data,mid+1,right,k);
        else if(data[mid] >k) return getLastK(data,left,mid-1,k);
        else if(data[mid] == k && data[mid+1] ==k)
            return getLastK(data,mid+1,right,k);
        else return mid;
    }
public:
    int GetNumberOfK(vector<int>& data, int k) {
        int n = data.size();
        if(n == 0) return 0;
        //not found ,return -1
        int firstK = getFirstK(data, 0, n - 1, k);
        int lastK = getLastK(data,0,n-1,k);
        if(firstK == -1) return 0;
        return lastK - firstK + 1;
    }
};

38. 输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

 1 /*
 2 struct TreeNode {
 3     int val;
 4     struct TreeNode *left;
 5     struct TreeNode *right;
 6     TreeNode(int x) :
 7             val(x), left(NULL), right(NULL) {
 8     }
 9 };*/
10 class Solution {
11 public:
12     int TreeDepth(TreeNode* pRoot) {
13         if (pRoot == nullptr) return 0;
14         int level = 0;
15         queue<TreeNode*> q1;
16         queue<TreeNode*> q2;
17         q1.push(pRoot);
18         while (!q1.empty()) {
19             level++;
20             while (!q1.empty()) {
21                 TreeNode* tmp = q1.front();
22                 q1.pop();
23                 if (tmp->left) q2.push(tmp->left);
24                 if (tmp->right) q2.push(tmp->right);
25             }
26             swap(q1, q2);
27         }
28         return level;
29     }
30 };

 

39.输入一棵二叉树,判断该二叉树是否是平衡二叉树。

 1 class Solution {
 2 private:
 3     bool IsBalanced(TreeNode* pRoot, int& depth) {
 4         if (pRoot == nullptr) {
 5             depth = 0;
 6             return true;
 7         }
 8         int leftDepth, rightDepth;
 9 
10         if (IsBalanced(pRoot->left, leftDepth)
11                 && IsBalanced(pRoot->right, rightDepth)) {
12             if(abs(leftDepth - rightDepth)<2){
13                 depth = max(leftDepth,rightDepth)+1;
14                 return true;
15             }
16         }
17         return false;
18     }
19 public:
20     bool IsBalanced_Solution(TreeNode* pRoot) {
21         if (pRoot == nullptr) return true;
22         int depth = 0;
23         return IsBalanced(pRoot, depth);
24     }
25 };

 40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

 1 class Solution {
 2 public:
 3     void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) {
 4         int n = data.size();
 5         int xorAll = 0;
 6         for (int i = 0; i < n; i++) {
 7             xorAll ^= data[i];
 8         }
 9         //find first bit is 1
10         unsigned int index = 0;
11         //与或操作记得加括号
12         while ((xorAll & 1) == 0 && index < 8 * sizeof(int)) {
13             index++;
14             xorAll = xorAll >> 1;
15         }
16         *num1 = 0;
17         *num2 = 0;
18         int splitNum = 1 << index;
19         for (int i = 0; i < n; i++) {
20             //与或操作要加括号
21             if ((data[i] & splitNum) == 0) {
22                 *num1 ^= data[i];
23             } else {
24                 *num2 ^= data[i];
25             }
26         }
27     }
28 };

 

剑指offer(36-40)编程题