编程之旅-Day9

目录

Day9-学习内容:

1.剑指Offer

面试题14:剪绳子

面试题24:反转链表

2.Leetcode

例1:给n个孩子分糖果,满足下列条件时求最少分发的糖果数。

例2:求二叉树的后序遍历。

3.2017年校招真题

例1:两种排序方法

4.校招真题-单选题

例1.下面哪一个不是动态链接库的优点

例2:n个数值选出最大m个数

例3:由权值分别为1、12、13、4、8的叶子节点生成一颗哈夫曼树,它的带权路径长度为


 

1.剑指Offer

面试题14:剪绳子

牛客网暂无对应练习题

 

面试题24:反转链表

题目描述:

输入一个链表,反转链表后,输出新链表的表头。

思路:1.需要使用三个指针用于保存当前节点、当前节点的前一个节点、当前节点的后一个节点(防止链表断裂)

            2.可借助图形帮助分析,反转链表的头节点为原来链表的尾节点

            3.需要考虑输入链表头指针为nullptr、只有一个节点、有多个节点等情况,注意代码的鲁棒性,方法是提前想好测试用例,利用测试用例对代码进行检查。

代码:

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        ListNode* ReverseHead=nullptr;
        ListNode* pNode=pHead;
        ListNode* pPre=nullptr;
        while(pNode!=nullptr){
            ListNode* pNext=pNode->next;
            if(pNext==nullptr){
                ReverseHead=pNode;
            }
            pNode->next=pPre;
            pPre=pNode;
            pNode=pNext;
        }
        return ReverseHead;
    }
};

2.Leetcode

例1:给n个孩子分糖果,满足下列条件时求最少分发的糖果数。

题目描述:

There are N children standing in a line. Each child is assigned a rating value. 

You are giving candies to these children subjected to the following requirements: 

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

思路:动态规划,因为是求最优问题且该问题能被分解成若干重复的子问题。

代码:

class Solution {
public:
    int candy(vector &ratings) {
        int len=ratings.size();
        if(len==1) return 1;   //只有一个孩子
        
        vector v(len,1);    //每个孩子先分一个糖果
        int sum=0;
        for(int i=1;iratings[i-1]){
                v[i]=v[i-1]+1;
            }
        }
        for(int i=len-2;i>=0;i--){    //从右向左扫描,保证该方向上ratings值越大分得的糖果越多
            if(ratings[i]>ratings[i+1]&&v[i]<=v[i+1]){
                v[i]=v[i+1]+1;
            }
        }
        for(int i=0;i

例2:求二叉树的后序遍历。

题目描述:

Given a binary tree, return the postorder traversal of its nodes' values. 

For example:
Given binary tree{1,#,2,3}, 

   1
    \
     2
    /
   3

 

return[3,2,1]. 

Note: Recursive solution is trivial, could you do it iteratively?

思路:巧妙的方法:前序遍历 根->左->右 变成 根->右->左 结果再reverse一下

代码:

class Solution {
public:
    vector postorderTraversal(TreeNode *root) {
        vector res;
        if(!root) return res;
        stack st;
        st.push(root);
        while(st.size()){
            TreeNode *temp=st.top();
            st.pop();
            res.push_back(temp->val);
            if(temp->left){
                st.push(temp->left);
            }
            if(temp->right){
                st.push(temp->right);
            }
        }
        reverse(res.begin(),res.end());
        return res;
    }
};

3.2017年校招真题

例1:两种排序方法

题目描述:

考拉有n个字符串字符串,任意两个字符串长度都是不同的。考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序。例如:
"car" < "carriage" < "cats" < "doggies < "koala"
2.根据字符串的长度排序。例如:
"car" < "cats" < "koala" < "doggies" < "carriage"
考拉想知道自己的这些字符串排列顺序是否满足这两种排序方法,考拉要忙着吃树叶,所以需要你来帮忙验证。

 输入描述:

输入第一行为字符串个数n(n ≤ 100)
接下来的n行,每行一个字符串,字符串长度均小于100,均由小写字母组成

输出描述:
如果这些字符串是根据字典序排列而不是根据长度排列输出"lexicographically",

如果根据长度排列而不是字典序排列输出"lengths",

如果两种方式都符合输出"both",否则输出"none"

示例1

输入

3 a aa bbb

输出

both

解析:1.Sort函数包含在头文件为#include的c++标准库中,Sort函数有三个参数:

(1)第一个是要排序的数组的起始地址。

(2)第二个是结束的地址(最后一位要排序的地址)

(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序。

模板:

Sort(start,end,排序方法)

参考:https://www.cnblogs.com/jjzzx/p/5122381.html

2.using namespace std的左右

C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。

参考:https://www.cnblogs.com/lauzhishuai/p/6382721.html

3.C语言和C++的区别

参考:https://blog.csdn.net/czc1997/article/details/81254971

4.逻辑否(!)是一元操作符,逻辑与(&&)是二元操作符,一元操作符的优先级高于任何二元操作符。

5.c++中也可以使用printf函数。

代码:

#include 
#include 
#include 

using namespace std;
bool cmp(string a,string b){
    return a.length()>n;
    for(int i=0;i>a[i];
        b[i]=a[i];
        c[i]=a[i];
    }
    sort(b,b+n);
    sort(c,c+n,cmp);
    if(equal(a,b,n)&&equal(a,c,n)) printf("both\n");
    if(equal(a,b,n)&&(!equal(a,c,n))) printf("lexicographically\n");
    if((!equal(a,b,n))&&equal(a,c,n)) printf("lengths\n");
    if((!equal(a,b,n))&&(!equal(a,c,n))) printf("none\n");
    
}

4.校招真题-单选题

例1.下面哪一个不是动态链接库的优点?(B)

A.共享 B.装载速度快 C.开发模式好 D.减少页面交换

解析:

1 静态链接库的优点  

 (1) 代码装载速度快,执行速度略比动态链接库快;  

 (2) 只需保证在开发者的计算机中有正确的.LIB文件,在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题。  

2 动态链接库的优点 

 (1) 更加节省内存并减少页面交换; 

 (2) DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回值类型和调用约定不变),更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性; 

 (3) 不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数; 

 (4)适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试。 

3 不足之处

 (1) 使用静态链接生成的可执行文件体积较大,包含相同的公共代码,造成浪费; 

 (2) 使用动态链接库的应用程序不是自完备的,它依赖的DLL模块也要存在,如果使用载入时动态链接,程序启动时发现DLL不存在,系统将终止程序并给出错误信息。而使用运行时动态链接,系统不会终止,但由于DLL中的导出函数不可用,程序会加载失败;速度比静态链接慢。当某个模块更新后,如果新模块与旧的模块不兼容,那么那些需要该模块才能运行的软件,统统撕掉。这在早期Windows中很常见。

 

例2:n个数值选出最大m个数(3

 A.O(n) B.O(nlogn) C.O(logn) D.O(mlogn) E.O(nlogm) F.O(mn)

解析:用快速选择算法平均时间复杂度为O(n),还可以用Median of medians,也叫BRPRT算法可以保证是O(n)的

 

例3:由权值分别为1、12、13、4、8的叶子节点生成一颗哈夫曼树,它的带权路径长度为(F)

A.12 B.68 C.43 D.6 E.25 F.81

解析:

Haffman树如下: 

        38

 *13          25

          *12      13

                   5      *8

              *1     *4      

其中带*为原始元素,总共4层(不算根节点) 带权路径长度 13*1 + 12*2 + 8*3 + (1+4)*4 = 81

 

你可能感兴趣的:(算法,编程,计算机,数据结构)