剑指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 };
时间: 2024-12-19 16:40:36

剑指offer(36-40)编程题的相关文章

剑指offer (36) 数组中的逆序对

题目:在数组中的两个数字如果前面一个数字大于后面一个数字,则这两个数字组成一个逆序对 题解分析: 首先应该想到很简单的一种解法,顺序遍历数组,对每个数,逐个比较该数字和其以后的数字,T(n) = O(n^2) (1)总体的意思就是将数组分成两段,首先求段内的逆序对数量,比如下面两段代码就是求左右两端数组段内的逆序对数量 count += Merge(data, temp, first, mid);//找左半段的逆序对数目 count += Merge(data, temp, mid + 1, e

【剑指offer】第四题 替换空格

/** * 剑指offer 第4题 替换空格 * 特点:1.先扫描串中的空格数,计算好替换后的长度 * 2.使用双指针,从后面开始向前替换,避免从前开始每次替换后就要移动后面的所有的数据 * 测试用例:特殊:有多个空格 * 错误:数组长度不够,字符串为空 * */ package javaTrain; public class Offer4 { public static void main(String[] args) { String a = "Hello I am Daisy Dong!&

【Java】 剑指offer(36) 二叉搜索树与双向链表

本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 思路 二叉搜索树.排序链表,想到使用中序遍历. 要实现双向链表,必须知道当前结点的前一个结点.根据中序遍历可以知道,当遍历到根结点的时候,左子树已经转化成了一个排序的链表了,根结点的前一结点就是该链表的最后一个结点(这个结点必须记录下来,将遍历函数的返回值设置

剑指offer第40题

1 package com.yan.offer; 2 3 /** 4 * 题目描述: 5 * 6 * 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 7 * 8 * @author Yan 9 * 10 */ 11 public class ArrayFindSingleNum { 12 13 public ArrayFindSingleNum() { 14 } 15 16 private static int[] arr = new int[] {

剑指offer第40题 数组中只出现一次的数字

#include<iostream> using namespace std; bool iswei1(int data,int wei) { int i=8*sizeof(int); data=data>>(i-wei); return(data&1); } void number1(int *list,int length,int *num1,int *num2) { int data=0; for(int i=0;i<length;i++) { data=dat

剑指offer第十八题 顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. 解题思路:一次去掉一个外圈,当最后只剩一行或一列时停止递归.(ps:这题就是绕,仔细点就解决了!!!) 1 import java.util.ArrayList; 2 public class Solution { 3 publ

《剑指offer》第十七题:打印1到最大的n位数

// 面试题17:打印1到最大的n位数 // 题目:输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则 // 打印出1.2.3一直到最大的3位数即999. #include <cstdio> #include <memory> void PrintNumber(char* number); bool Increment(char* number); void Print1ToMaxOfNDigitsRecursively(char* number, int length

《剑指offer》:[40]数组中只出现一次的数字

题目:一个整型数组里除了两个数字外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度为O(N),空间复杂度为O(1). 例如输入数组{2,4,3,6,3,2,5,5},因为只有4和6在这个数组里出现了一次,所以最后输出的是4,6. 分析:因为题目要求的时间复杂度和空间复杂度分别为:O(N)和O(1).所以这个题目不能借助辅助空间,那么也就是要在一次遍历后就能找出只出现一次的数据还是有一定的难度的.我在第一次看这个题目的时候也没想到什么好的办法.最后看了书上的提示才想到这

《剑指offer》之7-9题

7.斐波那契数列 问题描述 都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项. 实现思想 了解斐波那契数列的规律就Ok了.1,1,2,3,5,8,... 代码 function Fibonacci(n) { // write code here if(n==0||n==1){ return n; } var N1=1,N2=0; for(let i=2;i<=n;i++){ N1=N1+N2; N2=N1-N2; } return N1; } 8.跳台阶 问题描述 一只青

【剑指offer】 第三题 二维数组查找

package javaTrain; public class offer3 { public static void main(String args[]) { int[][] a = {{0,1,2,3},{1,2,3,4},{2,3,4,5},{6,7,8,9}}; System.out.println(find(a,10)); } public static boolean find(int[][] a,int num) { if(a == null) return false; int