剑指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 };