• C++面试题5


    第5课 - 外企笔试题精选三

    1. 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下的顺序排序。请实现一个函数用于判断数组中是否含有指定的数。

    函数原型:

             bool find_in_matrix(int matrix[N][M], int value);

    说明:

             查找成功时返回true,失败时返回false。

    答案:

    #include <iostream>

    using namespace std;

    template<typename T, int N, int M>

    bool find_in_matrix(T matrix[N][M], T value) // O(N + M)

    {

        if( (matrix[0][0] <= value) && (value <= matrix[N-1][M-1]) )

        {

            int r = 0;

            int c = M - 1;

            while( (r < N) && (c >= 0) )

            {

                if( value == matrix[r][c] )

                {

                    return true;

                }

                else if( value < matrix[r][c] )

                {

                    c--;

                }

                else

                {

                    r++;

                }

            }

        }

        return false;

    }

    int main()

    {

        int matrix[4][4] =

        {

            {1, 2, 8, 9},

            {2, 4, 9, 12},

            {4, 7, 10, 13},

            {6, 8, 11, 15},

        };

        cout<<find_in_matrix<int, 4, 4>(matrix, 7)<<endl;

        return 0;

    }

    1. 写一个函数,打印二叉树中某层的所有结点。

    二叉树结点定义:

    struct Node

    {

             int v;

             Node* left;

             Node* right;

    };

    函数原型:

    void print_node_at_level(Node* node, int level)

    说明:将level层的结点中所保存的值打印在同一行。

    分析:二叉树的题是离不开递归的

    #include <iostream>

    #include <list>

    using namespace std;

    struct Node

    {

        int v;

        Node* left;

        Node* right;

    };

    void print_node_at_level(Node* node, int level)  //递归的答案,答案简介,但是耗费函数调用栈

    {

        if( node != NULL )

        {

            if( level == 0 ) //若是第0层,直接打印

            {

                cout<<node->v<<" ";

            }

            else //若不是第0层,递归的打印

            {

                print_node_at_level(node->left, level-1);

                print_node_at_level(node->right, level-1);

            }

        }

    }

    void print_node_at_level_ex(Node* node, int level)  //非递归的方式,广度优先算法

    {

        if( node != NULL )  //为每个元素编号

        {

            list<Node*> nl; 

            list<int> ll;

            nl.push_back(node);

            ll.push_back(0);

            while( nl.size() > 0 )

            {

                Node* n = nl.front();

                int cl = ll.front();

                nl.pop_front();

                ll.pop_front();

                if( cl == level )

                {

                    cout<<n->v<<" ";

                }

                else if( cl < level )

                {

                    if( n->left != NULL )

                    {

                        nl.push_back(n->left);

                        ll.push_back(cl+1);

                    }              

                    if( n->right != NULL )

                    {

                        nl.push_back(n->right);

                        ll.push_back(cl+1);

                    }

                }

            }

        }

    }

    int main()

    {

        Node nodes[] =

        {

            {0, NULL, NULL},  //0层

            {1, NULL, NULL},  //1层

            {2, NULL, NULL},  //1层

            {3, NULL, NULL},  //2层

            {4, NULL, NULL},  //2层

            {5, NULL, NULL},  //2层

            {6, NULL, NULL},  //3层

            {7, NULL, NULL},  //3层

        };

       

        nodes[0].left  = &nodes[1]; //0指向1,2   ,0层

        nodes[0].right = &nodes[2];

        nodes[1].left  = &nodes[3];  //1指向3,4 ,1层

        nodes[1].right = &nodes[4];

        nodes[2].left  = &nodes[5];  //2左指5,右指向空, 1层

        nodes[2].right = NULL;

        nodes[4].left  = &nodes[6]; //4指向4,5   ,2层

        nodes[4].right = &nodes[7];

        print_node_at_level(nodes, 3);  //6,7

        cout<<endl;

        //print_node_at_level_ex(nodes, 3);

        cout<<endl;

        return 0;

    }

    1. 编写一个函数用于删除二叉树中的度数为1的所有结点。

    要求:

    结点删除后其唯一的子结点代替它的位置。

     

    答案:

    #include <iostream>

    using namespace std;

    struct Node

    {

        int v;

        Node* left;

        Node* right;

    };

    void print_div(int p)

    {

        for(int i=0; i<p; i++)

        {

            cout<<"-";

        }

    }

    void print_tree(Node* node, int p)

    {

        if( node != NULL )

        {

            print_div(p);

            cout<<node->v<<endl;

            if( (node->left != NULL) || (node->right != NULL) )

            {

                print_tree(node->left, p+1);

                print_tree(node->right, p+1);

            }

        }

        else

        {

            print_div(p);

            cout<<endl;

        }

    }

    void print_tree(Node* node)

    {

        print_tree(node, 0);

    }

    void delete_one_degree_node(Node*& node)

    {

        if( node != NULL )

        {

            if( (node->left != NULL) && (node->right != NULL) )  //度数为2

            {

                delete_one_degree_node(node->left);  //删除左子树的单度结点

                delete_one_degree_node(node->right); //删除右子树的单度结点

            }

            else if( (node->left != NULL) && (node->right == NULL) )   //度数为1

            {

                node = node->left;

                delete_one_degree_node(node); //新的结点也要进行单度删除

            }

            else if( (node->left == NULL) && (node->right != NULL) )   //度数为1

            {

                node = node->right;         

                delete_one_degree_node(node); //新的结点也要进行单度删除

            }

        }

    }

    int main()

    {

        Node n[10] = {0};

        Node* tree = n;

        for(int i=0; i<10; i++)

        {

            n[i].v = i;

        }

        tree[0].left = &tree[1];

        tree[0].right = &tree[2];

        tree[1].left = &tree[3];

        tree[1].right = &tree[4];

        tree[2].left = NULL;

        tree[2].right = &tree[6];

        tree[3].left = &tree[7];

        tree[3].right = &tree[8];

        tree[4].left = &tree[9];

        cout<<"Original:"<<endl;

        print_tree(tree);

        delete_one_degree_node(tree);

        cout<<"After:"<<endl;

        print_tree(tree);

        return 0;

    }

    1. 输入一个数组,数组里面可能有正数也有负数。数组中一个或连续的多个元素组成一个子数组。求所有子数组的和的最大值。

    要求:

    时间复杂度为O(n)。

    答案:

    #include <iostream>

    #include <cstdlib>

    #include <ctime>

    using namespace std;

    template<typename T>

    void init(T array[], int len)

    {

        srand((unsigned int)(time(NULL)));

        for(int i=0; i<len; i++)

        {

            array[i] = rand() % 10 - 5;    

        }

    }

    template<typename T>

    void print_array(T array[], int len)

    {

        for(int i=0; i<len; i++)

        {

            cout<<array[i]<<" ";

        }

        cout<<endl;

    }

    template<typename T>

    bool max_sub_array_sum(T array[], int len, T& max_sum)

    {

        int ret = (len > 1);

        if( ret )

        {

            T sum = array[0];

            T cur = array[0];

            for(int i=1; i<len; i++)

            {

                cur = cur + array[i];

                if( cur < array[i] )  //array[i]之前的值是负数的话,直接从array[i]开始

                {//若果部分和比当前的元素小,舍弃部分和

                    cur = array[i];

                }

                if( cur > sum )

                {

                    sum = cur;

                }

            }   

            max_sum = sum;

        }

        return ret;

    }

    int main()

    {

        int array[10] = {0};

        int max_sum = 0;

        init(array, 10);

        print_array(array, 10);

        if( max_sub_array_sum(array, 10, max_sum) )

        {

            cout<<max_sum<<endl;

        }

        return 0;

    }

    1. 在一个整型数组中只可能有0, 1, 2三种数字重复出现,编写一个函数对这样的数组进行排序。

    答案:

    #include <iostream>

    #include <cstdlib>

    #include <ctime>

    using namespace std;

    void init(int array[], int len)//初始化

    {

        srand((unsigned int)(time(NULL)));

        for(int i=0; i<len; i++)

        {

            array[i] = rand() % 3;    

        }

    }

    void print_array(int array[], int len)//打印

    {

        for(int i=0; i<len; i++)

        {

            cout<<array[i]<<" ";

        }

        cout<<endl;

    }

    void swap(int& a, int& b) //交换

    {

        int c = a;

        a = b;

        b = c;

    }

    void three_element_sort(int array[], int len)

    {

        int* ts = new int[len];

        int p = 0;

        if( ts != NULL )

        {

            for(int i=0; i<3; i++)

            {

                for(int j=0; j<len; j++)

                {

                    if( array[j] == i )

                    {

                        ts[p++] = i;

                    }

                }

            }

            for(int i=0; i<len; i++)

            {

                array[i] = ts[i];

            }

            delete[]ts;

        }

    }

    void three_element_sort_ex(int array[], int len)

    {

        int p0 = 0;

        int p2 = len - 1;

        while( array[p0] == 0 ) p0++;

        while( array[p2] == 2 ) p2--;

        for(int i=p0; i<=p2;)

        {

            if( array[i] == 0 )

            {

                swap(array[i], array[p0++]);  

                while( array[p0] == 0 ) p0++;

                if( i < p0 ) i = p0;

            }

            else if( array[i] == 2 )

            {

                swap(array[i], array[p2--]);

               

                while( array[p2] == 2 ) p2--;

            }

            else

            {

                i++;

            }

        }

    }

    int main()

    {

        int array[15] = {2, 2, 2, 0, 2, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0};

        init(array, 15);

        print_array(array, 15);

        //three_element_sort(array, 15);

        three_element_sort_ex(array, 15);

        print_array(array, 15);

       

        return 0;

    }

    1. 求1+2+3+…n的和。

    要求:

    不能使用if, while, for, switch, ?:等条件语句,不能使用==, !=, <, <=, >, >=等比较运算符,也不能使用外部库函数。只能使用加减法操作符,不能使用乘除法操作符。

    答案一:

    #include <iostream>

    using namespace std;

    class Sum

    {

    private:

        static int N;

        static int S;

        Sum();

    public:

        static int Calculate(int n);

    };

    int Sum::N = 0;

    int Sum::S = 0;

    Sum::Sum()

    {

        S = S + N;

        N = N - 1;

    }

    int Sum::Calculate(int n)

    {

        int ret = 0;

        Sum* p = NULL; 

        N = n;

        S = 0;

        p = new Sum[N];

        ret = S;      

        delete[]p;

        return ret;

    }

    int main()

    {

        cout<<Sum::Calculate(10)<<endl;

        cout<<Sum::Calculate(100)<<endl;

        return 0;

    }

    答案二:

    #include <iostream>

    using namespace std;

    typedef int(Func)(int);

    int end_func(int n);

    int recusive_func(int n);

    Func* Array[] =  //函数指针

    {

        end_func,     // 0

        recusive_func // 1

    };

    int end_func(int n)

    {

        return n;

    }

    int recusive_func(int n)

    {

        return n + Array[!!(n-1)](n-1);  //!!将不为0的数变成1

    }

    int sum(int n)

    {

        return recusive_func(n);

    }

    int main()

    {

        cout<<sum(10)<<endl;

        cout<<sum(100)<<endl;

        return 0;

    }

    答案三:

    #include <iostream>

    using namespace std;

    template<int N>

    class Sum

    {

    public:

        static const int Value = N + Sum<N-1>::Value;

    };

    template<>

    class Sum<0>

    {

    public:

        static const int Value = 0;

    };

    int main()

    {

        cout<<Sum<10>::Value<<endl;

        cout<<Sum<100>::Value<<endl;

       

        return 0;

    }

  • 相关阅读:
    Redis 中如何保证数据的不丢失,Redis 中的持久化是如何进行的
    Redis 中的 set 和 sorted set 如何使用,源码实现分析
    Redis 中使用 list,streams,pub/sub 几种方式实现消息队列
    Redis 中 String 类型的内存开销比较大
    为什么 Redis 的查询很快, Redis 如何保证查询的高效
    Redis 中常见的集群部署方案
    2021 年终总结
    linux挂载大于2T的移动硬盘
    maven编译报错
    Docker命令详解
  • 原文地址:https://www.cnblogs.com/free-1122/p/11341969.html
Copyright © 2020-2023  润新知