现在的位置: 首页 > 综合 > 正文

面试题整理(四)

2018年02月21日 ⁄ 综合 ⁄ 共 3713字 ⁄ 字号 评论关闭
/*
第11题
------------------------------------
求二叉树中节点的最大距离...

  如果我们把二叉树看成一个图,
  父子节点之间的连线看成是双向的,
  我们姑且定义"距离"为两节点之间边的个数。
  写一个程序,
  求一棵二叉树中相距最远的两个节点之间的距离。
*/

//July  2010/10/19
//此题思路,tree_star and i 在257、258楼,讲的很明白了。

//定义 一个 结构体
struct NODE
{  
    NODE* pLeft;
    NODE* pRight;
    int MaxLen;
    int MaxRgt;
};   
NODE* pRoot;  //根节点
int MaxLength;

void traversal_MaxLen(NODE* pRoot)
{ 
    if(pRoot == NULL)
    {
        return 0;
    };
    
    if(pRoot->pLeft == NULL)    
    {
        pRoot->MaxLeft = 0;
    }
    else                                 //若左子树不为空
    {
        int TempLen = 0;
        if(pRoot->pLeft->MaxLeft > pRoot->pLeft->MaxRight)
          //左子树上的,某一节点,往左边大,还是往右边大
        {
            TempLen+=pRoot->pLeft->MaxLeft;
        }
        else
        {
            TempLen+=pRoot->pLeft->MaxRight;
        }
        pRoot->nMaxLeft = TempLen + 1;
        traversal_MaxLen(NODE* pRoot->pLeft); 
        //此处,加上递归
    }
    
    
    if(pRoot->pRigth == NULL)
    {
        pRoot->MaxRight = 0;
    }
    else                                //若右子树不为空
    {
        int TempLen = 0;
        if(pRoot->pRight->MaxLeft > pRoot->pRight->MaxRight)  
        //右子树上的,某一节点,往左边大,还是往右边大
        {
            TempLen+=pRoot->pRight->MaxLeft;
        }
        else
        {
            TempLen+=pRoot->pRight->MaxRight;
        }
        pRoot->MaxRight = TempLen + 1;
        traversal_MaxLen(NODE* pRoot->pRight); 
        //此处,加上递归
    }
    
    if(pRoot->MaxLeft + pRoot->MaxRight > 0)
    {
        MaxLength=MaxLeft + MaxRight;
    }
}

/*
第12题
题目:求1+2+…+n,
要求不能使用乘除法、for、while、if、else、switch、case等关键字
以及条件判断语句(A?B:C)。

*/


//July、2010/10/19

/*-----------------
循环只是让相同的代码执行n遍而已,我们完全可以不用for和while达到这个效果。
比如定义一个类,我们new一含有n个这种类型元素的数组,
那么该类的构造函数将确定会被调用n次。我们可以将需要执行的代码放到构造函数里。
------------------*/

#include <iostream.h>

class Temp
{
public:
      Temp() 
      {
          ++N; 
          Sum += N;
      }
      static void Reset() { N = 0; Sum = 0; }
      static int GetSum() { return Sum; }

private:
      static int N;
      static int Sum;
};

int Temp::N = 0;
int Temp::Sum = 0;

int solution1_Sum(int n)
{
      Temp::Reset();

      Temp *a = new Temp[n];   //就是这个意思,new出n个数组。
       delete []a;
      a = 0;

      return Temp::GetSum();
}

int main()
{
    cout<<solution1_Sum(100)<<endl;
    return 0;
}

//运行结果:
//5050
//Press any key to continue

/*
第13题:
题目:
输入一个单向链表,输出该链表中倒数第k个结点,
链表的倒数第0个结点为链表的尾指针。
*/

//此题一出,相信,稍微有点 经验的同志,都会说到:
/*------------------------
设置两个指针p1,p2
首先p1和p2都指向head
然后p2向前走n步,这样p1和p2之间就间隔k个节点
然后p1和p2同时向前步进,当p2到达最后一个节点时,p1就是倒数第k个节点了
-------------------------*/

//July、2010/10/19

//好了,请你指出 下述代码的错误?:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>

struct ListNode
{
    char data;
    ListNode* next;
};
ListNode* head,*p,*q;
ListNode *pone,*ptwo;

int fun(ListNode *head,int k)
{
    pone = ptwo = head;
    for(int i=0;i<=k;i++)
        ptwo=ptwo->next;
    while(ptwo!=NULL)
    {
        pone=pone->next;
        ptwo=ptwo->next;
    }
    return pone->data;
}

int main()
{
    char c;
    head = (ListNode*)malloc(sizeof(ListNode));
    head->next = NULL;
    p = head;
    c = getchar();
    while(c !='0')
    {
        q = (ListNode*)malloc(sizeof(ListNode));
        q->data = c;
        q->next = NULL;
        p->next = q;
        p = p->next;
        c = getchar();
    }
    cout<<"---------------"<<endl;
    cout<<fun(head,2)<<endl;  

    return 0;
}

/*
第14题:
题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(n)。

  如果有多对数字的和等于输入的数字,输出任意一对即可。
  例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。
*/



//由于数组已经过升序排列,所以,难度下降了不少。

//July、2010/10/19
#include <iostream.h>

bool FindTwoNumbersWithSum
(
 int data[],           // 已经排序的 数组
 unsigned int length,  // 数组长度    
 int sum,              //用户输入的 sum 
 int& num1,            // 输出符合和等于sum的第一个数
 int& num2             // 第二个数
 )
{    
    bool found = false;
    if(length < 1)
        return found;
    
    int begin = 0;
    int end = length - 1;
    
    while(end > begin)
    {
        long curSum = data[begin] + data[end];
        
        if(curSum == sum)
        {
            num1 = data[begin];
            num2 = data[end];
            found = true;
            break;
        }
        else if(curSum > sum)
            end--;
        else
            begin++;
    }
    return found;
}


int main()
{
    int x,y;
    int a[6]={1,2,4,7,11,15};
    if(FindTwoNumbersWithSum(a,6,15,x,y) )
    {
        cout<<x<<endl<<y<<endl;
    }
    return 0;
}
/*-----------------
4
11
Press any key to continue
-----------------*/




//扩展:如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变,
//如何在O(n)时间里找到这两个数字?

/*
第15题:
题目:输入一颗二元查找树,将该树转换为它的镜像,
即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
用递归和循环两种方法完成树的镜像转换。   
例如输入:
   8
  / \
 6  10
/ \ / \
5 7 9 11

输出:
    8
   / \
  10  6
 / \ / \
11 9 7  5

定义二元查找树的结点为:
struct BSTreeNode // a node in the binary search tree (BST)
{
  int m_nValue; // value of node
  BSTreeNode *m_pLeft; // left child of node
  BSTreeNode *m_pRight; // right child of node
};
*/


//就是递归 翻转树,有子树则递归翻转子树。
//July、2010/10/19

void Revertsetree(list *root)
{
    if(!root)
       return;
    list *p;

    p=root->leftch;
    root->leftch=root->rightch;
    root->rightch=p;

    if(root->leftch)
      Revertsetree(root->leftch);
    if(root->rightch)
      Revertsetree(root->rightch);
}

抱歉!评论已关闭.