程序员面试题精选100题:6-10解题报告

程序员面试题精选100题(06)-二元查找树的后序遍历结果[数据结构]  

题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。如果是返回true,否则返回false。

例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:

         8
       /  \
      6    10
    / \    / \
   5   7   9  11

因此返回true。

如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。

分析:递归问题

#include <iostream>

using namespace std;

bool check(int arry[],int beg,int end)
{
    if(beg > end || arry==NULL)
    {
       return false;
    }
    if(beg == end)
        return true;
    int change = end;
    while(true)
    {
       if(change>=beg && arry[change] >= arry[end])
       {
          change--;
       }
       else
           break;
    }
    /*int change = end-1;
    for(;change>=0;--change)
    {
       if(arry[change]<arry[end])
           break;
    }*/
    int left = change;
    while(left>=beg && arry[left]<arry[end])
    {
       left--;
    }
    if(left>=beg)
        return false;
    //recurs
    return check(arry,beg,change) && check(arry,change+1,end-1);
}

int main()
{
    //int arry[] = {5,7,6,9,11,10,8};
    int arry[] = {7,4,6,5};
    bool ispostorder = check(arry,0,sizeof(arry)/sizeof(int)-1);
    if(ispostorder)
        cout << "yes postorder..." << endl;
    else
        cout << "not postorder..." << endl;
    return 0;
}
答案:
bool verifySquenceOfBST(int squence[], int length)
{
      if(squence == NULL || length <= 0)
            return false;

      // root of a BST is at the end of post order traversal squence
      int root = squence[length - 1];

      // the nodes in left sub-tree are less than the root
      int i = 0;
      for(; i < length - 1; ++ i)
      {
            if(squence[i] > root)
                  break;
      }

      // the nodes in the right sub-tree are greater than the root
      int j = i;
      for(; j < length - 1; ++ j)
      {
            if(squence[j] < root)
                  return false;
      }

      // verify whether the left sub-tree is a BST
      bool left = true;
      if(i > 0)
            left = verifySquenceOfBST(squence, i);

      // verify whether the right sub-tree is a BST
      bool right = true;
      if(i < length - 1)
            right = verifySquenceOfBST(squence + i, length - i - 1);

      return (left && right);
}

从左到右,感觉这里for比while好些,oj上没有AC不知道没考虑那种情况???

=====================================================

程序员面试题精选100题(07)-翻转句子中单词的顺序[算法]  

题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。

例如输入“I am astudent.”,则输出“student. a am I”。

由于本题需要翻转句子,我们先颠倒句子中的所有字符。这时,不但翻转了句子中单词的顺序,而且单词内字符也被翻转了。我们再颠倒每个单词内的字符。由于单词内的字符被翻转两次,因此顺序仍然和输入时的顺序保持一致。

也可以先翻转单词顺序,然后再全部翻转

扩展:左旋右旋问题

 

========================================================

程序员面试题精选100题(08)-求1+2+...+n[C/C++/C#] 

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

这个的确够发散,定义一个类,我们new一含有n个这种类型元素的数组,那么该类的构造函数将确定会被调用n次

============================================================

 

程序员面试题精选100题(09)-链表中倒数第k个结点[数据结构]  

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

分析:快慢指针。

扩展:输入一个单向链表。如果该链表的结点数为奇数,输出中间的结点;如果链表结点数为偶数,输出中间两个结点前面的一个

 

==================================================================

程序员面试题精选100题(10)-排序数组中和为给定值的两个数字[算法] 

题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(n)。如果有多对数字的和等于输入的数字,输出任意一对即可。

例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。

分析:1.暴力C(2,n)复杂度O(n^2)

2.这个没用利用到有序这个条件,优化两个指针向中间靠拢。复杂度O(n)

 

扩展:

1.输入一个数组,判断这个数组中是不是存在三个数字i, j, k,满足i+j+k等于0

先排序O(nlogn),然后对于每个元素,采用上述算法判断是否有两个数和为该值,复杂度为O(n^2)

 

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

知道数字范围那就计数排序呗,其他同O(n)

3. 如果不知道数字范围呢?

这个就要依靠hash了,先O(n)hash,然后对于A查找是否hash存在K-A,存在即找到。复杂度O(n)

 

4. google面试题:无序数组是否存在连续几个数的和等于N

分析:1.暴力O(n^3)

2.优化下f(I,n)=f(I,n-1)+a[i][n]一趟O(n),对于n个i总复杂度为O(n^2)

3.快慢指针I,j。如果小于K,j增加;否则i增加,需要注意I==J的情况,ij不回溯,最多2n步,所以复杂度为O(n)


你可能感兴趣的:(面试题,剑指offer100题)