编程之旅-Day14

目录

Day14-学习内容

1.剑指Offer

面试题9:用两个栈实现队列

面试题50:第一个只出现一次的字符

2.Leetcode

例1:平衡二叉树

例2:格式化文本

3.2018年校招编程题

例1:爱奇艺-判断题

例2:网易-等差数组

4.2017阿里巴巴暑期实习笔试题


1.剑指Offer

面试题9:用两个栈实现队列

题目描述:

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路:

1.用两个栈实现一个队列的功能?要求给出算法和思路!<分析>:

入队:将元素进栈A

出队:判断栈B是否为空,如果为空,则将栈A中所有元素pop,并push进栈B,栈B出栈;

 如果不为空,栈B直接出栈。

2.用两个队列实现一个栈的功能?要求给出算法和思路!<分析>:

入栈:将元素进队列A

出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素   以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把   队列B中的元素出队列以此放入队列A中。

代码:

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
        if(stack2.empty()){
            while(!stack1.empty()){
                int node=stack1.top();
                stack1.pop();
                stack2.push(node);
            }
        }
        int node=stack2.top();
        stack2.pop();
        return node;
    }

private:
    stack stack1;
    stack stack2;
};

面试题50:第一个只出现一次的字符

题目描述:

在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

思路:1.由于char是一个8位的数据类型,共有256种可能,所以使用含有256个字符的数组作为哈希表,将字符对应的ASCII码值作为数组下标,出现的次数作为数组的值进行存储。

           2.一共两次遍历,第一次遍历字符串中字符出现的次数存在哈希表中,时间复杂度为O(n),第二次从头遍历字符串找出在第一个在哈希表中次数为1的字符对应的位置,时间复杂度为O(n),故总的时间复杂度为O(n),需要包含一个256个字符的辅助数组,由于数组大小是常数,故空间复杂度为O(1).

代码:

class Solution {
public:
    int FirstNotRepeatingChar(string str) {
        if(str.empty()) return -1;
        int size=256;
        int hashtable[size];
        for(int i=0;i<256;i++){
            hashtable[i]=0;
        }
        
        for(int i=0;i

2.Leetcode

例1:平衡二叉树

题目描述:

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

代码:

方法1

class Solution {
public:
    bool isBalanced(TreeNode *root) {
        if(root==nullptr) return true;
        int depth=0;
        return isBalanced_Core(root,depth);
    }
     bool isBalanced_Core(TreeNode *root, int &depth){
         if(root==nullptr){
             depth=0;
             return true;
         }
         int left,right;
         if(isBalanced_Core(root->left,left)&&isBalanced_Core(root->right,right)){
             if(abs(left-right)<=1){
                 depth=max(left,right)+1;
                 return true;
             }
         }
         return false;
    }
};

方法2:

思路:先写一个函数来求最大深度,对于二叉树的每一个节点,都求它的左子树和右子树的最大深度,如果两个深度之间的差大于1,那么就返回false。不断递归判断即可。

class Solution {
public:
    bool isBalanced(TreeNode *root) {
        if (root == NULL) { return true; }
        if (abs(maxDepth(root->left) - maxDepth(root->right)) > 1) {
            return false;
        }
        return isBalanced(root->left) and isBalanced(root->right);
 
    }
 
    int maxDepth(TreeNode *root) {
        if (root == NULL) { return 0; }
        return max(maxDepth(root->left), maxDepth(root->right)) + 1;
    }
};

 

例2:格式化文本

题目描述:

Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces' 'when necessary so that each line has exactly L characters.

Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

For the last line of text, it should be left justified and no extra space is inserted between words.

For example,
words:["This", "is", "an", "example", "of", "text", "justification."]
L:16.

Return the formatted lines as:

[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Note: Each word is guaranteed not to exceed L in length.
Corner Cases:
A line other than the last line might contain only one word. What should you do in this case?In this case, that line should be left-justified.

思路:首先要做的就是确定每一行能放下的单词数,就是比较n个单词的长度和加上n -1个空格的长度跟给定的长度L来比较即可,找到了一行能放下的单词个数,然后计算出这一行存在的空格的个数, 是用给定的长度L减去这一行所有单词的长度和。得到了空格的个数之后,就要在每个单词后面插入这些空格,这里有两种情况, 比如某一行有两个单词"to"和"a",给定长度L为6,如果这行不是最后一行,那么应该输出"to a",如果是最后一行,则应该输出 "to a",所以这里需要分情况讨论,最后一行的处理方法和其他行之间略有不同。最后一个难点就是,如果一行有三个单词,这时候中间有两个空,如果空格数不是2的倍数,

那么左边的空间里要比右边的空间里多加入一个空格,那么我们只需要用总的空格数除以空间个数,能除尽最好,说明能平均分配,除不尽的话就多加个空格放在左边的空间里。

代码:

class Solution {
public:
    vector fullJustify(vector &words, int L) {
        vector res;
        for(int i=0,j;i0){
                    str+=" ";
                }
                str+=words[k];
            }
            str+=string(L-str.size(),' ');
            res.push_back(str);  
        }
        return res;
    }
};

 

3.2018年校招编程题

例1:爱奇艺-判断题

题目描述:

牛牛参加了一场考试,考试包括n道判断题,每做对一道题获得1分,牛牛考试前完全没有准备,所以考试只能看缘分了,牛牛在考试中一共猜测了t道题目的答案是"正确",其他的牛牛猜为"错误"。考试结束后牛牛知道实际上n道题中有a个题目的答案应该是"正确",但是牛牛不知道具体是哪些题目,牛牛希望你能帮助他计算可能获得的最高的考试分数是多少。

输入描述:

输入包括一行,一行中有三个正整数n, t, a(1 ≤ n, t, a ≤ 50), 以空格分割

输出描述:
输出一个整数,表示牛牛可能获得的最高分是多少。

示例1

输入

3 1 2

输出
2

思路:最大分数相关的只有猜测为正确的数量和真正正确的数量,两个数的差就是丢失的分数,用总题目数减去丢失的分数,就是最大的分数

代码:

#include 

using namespace std;

int main(){
    int n,t,a;
    cin>>n>>t>>a;
    if(t>a){
        cout<

注意:不能写成cin>>n>>t>>a>>endl;会提示函数参数过多报错。

原因:cin是c++标准输入流,后面是不需要加endl;cout后面加endl是换行的意思,和"\n"的意思差不多!换行是输入不进去的,只有在输出的时候才能显示“换行”,换行输出,相当于\n ,所以endl不能和cin一起使用。

 

例2:网易-等差数组

题目描述:

如果一个数列S满足对于所有的合法的i,都有S[i + 1] = S[i] + d, 这里的d也可以是负数和零,我们就称数列S为等差数列。
小易现在有一个长度为n的数列x,小易想把x变为一个等差数列。小易允许在数列上做交换任意两个位置的数值的操作,并且交换操作允许交换多次。但是有些数列通过交换还是不能变成等差数列,小易需要判别一个数列是否能通过交换操作变成等差数列

输入描述:

输入包括两行,第一行包含整数n(2 ≤ n ≤ 50),即数列的长度。
第二行n个元素x[i](0 ≤ x[i] ≤ 1000),即数列中的每个整数。

输出描述:
如果可以变成等差数列输出"Possible",否则输出"Impossible"。

示例1

  输入

3
3 1 2

输出
Possible

思路:对数组排序后判断差值是否相等。

代码:

#include 
#include 
#include 
using namespace std;

int main(){
    int n;
    cin>>n;
    vector array(n); //必须声明为array(n)即指定二维数组的大小,声明array表示一个向量,会报越界错误
    for(int i=0;i>array[i];
    }
    sort(array.begin(),array.end());
    int d=array[1]-array[0];
    for(int i=1;i

 

扩展:

1.vector操作

介绍

1.vector数组是一个能存放任意数据类型(类,结构,普通变量类型等)的动态数组!,在数据结构中就相当于顺序储存的线性表,寻找元素非常快,但是插入元素的时间却很大(list是一个双向链表,在同一个为止插入大量的数据时速度很快,但是查找的速度就会慢很多)

2.和普通数组一样可以通过下标索引来进行访问

3.与其它动态序列容器相比(deques, lists and forward_lists), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起lists和forward_lists统一的迭代器和引用更好。

4.vector动态数组可以通过数组名进行直接赋值!  vector c;   vector b;    b = c; 

5.他的缺点:当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。(比普通的数组具有更高的时间复杂度和空间复杂度

数组插入元素:

1.vec.push_back(同类型量);作用是在vector的末尾插入新元素;

2.insert()第一个参数为迭代器,作用为在迭代器前面插入新元素;

3.assign(5,1)向vector中加入5个1,同时清除掉以前的元素。

删除元素: 

1.pop_back()删除最后一个元素。

2.erase()删除指定位置元素。(其中的参数要是指针变量,比如begain(),end(),以及迭代器值),例如vec.erase(vec.begin()+2);删除第3个元素

3.clear()清除所有元素。

4.empty()判断该数组是否为空

遍历数组:

1.front()访问第一个元素(第一个元素的值而不是地址!begin()相反)

2.back()访问最后一个元素(最后一个元素的值而不是地址!end()相反)

3.size()数组的元素个数

排序:

reverse(vec.begin(), vec.end())//将元素翻转,即逆序排列!

sort(vec.begin(), vec.end()); //采用的是从小到大的排序

https://www.cnblogs.com/yskn/p/9053161.html

 

4.2017阿里巴巴暑期实习笔试题

例17.刚毕业的小王上班有两路公交车都可以从家到公司.如果只等A车,平均需要5分钟才等到;如果只等B车,平均需要7分钟才能等到.假定两辆车运行时间独立,那么小王平均需要等多长时间才能等到A车或B车?(C)

A.2分钟 B.2分35秒 C.2分55秒 D.3分钟 E.5分钟 F.6分钟

解析:时间段t内A车 t/5趟,B车 t/7趟,所以在t内等到车共计t/5+t/7趟,等到一趟的时间则为t/(t/5+t/7),等价35/12。

 

例18.一个黑色袋子中装有5个红球,5个蓝球,5个黄球,从中抽取三次,每次抽一个球,取完不放回,则每种颜色球各得一个的概率是(E)

A.1/5 B.1/4 C.1/3 D.12/91 E.20/91

解析:C(3,1)*5/15 *C(3,2) *5/14 *5/13=25/91

 

例19.

1

2

3

int* pint = 0; 

pint += 6; 

cout << pint << endl;

以上程序的运行结果是:(C)

A.12 B.72 C.24 D.0 E.6 F.任意数

解析:第一句的意思是将pint指针指向0地址处,由于指针类型是int,每次加1相当于移动四个字节,(在int为四个字节的机器上);加上6,地址为0x18=24。

 

例20.某种5号(AA)充电电池在充满电之后的电量是900毫安时和1100毫安时的可能性各为1/2。如果将将电池串联使用,常常会因为其中一部分电池先放电完毕,而且其它电池还有100毫安时以上的电量时,引起先放完电的电池损坏。那么以下说法正确的是:(C)

A.如果两节这样的电池串联使用,那么必然有1节电池会损坏。
B.如果有许多节这样的电池串联使用,则至少会有1节电池会损坏。
C.如果放电电量控制在900毫安时以内,则不会有电池损坏
D.当有2n节电池串联使用时,至多会有n节电池会损坏
E.当串联的电池个数是奇数时,不会有电池损坏。
F.电量少的电池一定会损坏。

例21:下面哪种协议在数据链路层?(F)

A.ARP B.ICMP C.FTP D.UDP E.HTTP F.VPN

解析:
ICMP是网络层,UDP是传输层,FTP和HTTP是应用层 目前VPN隧道协议主要有4种:点到点隧道协议PPTP、第二层隧道协议L2TP、网络层隧道协议IPSec以及SOCKS v5协议。其中,PPTP和L2TP工作在数据链路层,IPSec工作在网络层,SOCK v5工作在会话层。

ARP和RARP 是网络层的协议,但是它所工作的内容是链路层的,具体来说应该是在网络层。
地址解析协议(Address Resolution Protocol,ARP)是在仅知道主机的IP地址时确定其物理地址的一种协议。因IPv4和以太网的广泛应用,其主要用作将IP地址翻译为以太网的MAC地址,但其也能在ATM和FDDIIP网络中使用。从IP地址到物理地址的映射有两种方式:表格方式和非表格方式。ARP具体说来就是将网络层(IP层,也就是相当于OSI的第三层)地址解析为数据连接层(MAC层,也就是相当于OSI的第二层)的MAC地址。

 

例22.一组记录排序码为(5 11 7 2 3 17),则利用堆排序方法建立的初始堆为(C)

A.(11 5 7 2 3 17)
B.(11 5 7 2 13 3)
C.(17 11 7 2 3 5)
D.(17 11 7 5 3 2)
E.(17 7 11 3 5 2)
F.(17 7 11 3 2 5)

构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:这样就得到了初始堆。
即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。
编程之旅-Day14_第1张图片

 例23:甲乙丙三人是阿里巴巴开发人员,ABC三人是阿里巴巴测试人员,每个开发都有对应的测试人员。主管介绍说:“A对应的开发是乙的好友,并在三个开发中最年轻;丙的年龄比C对应的开发大。”则开发和测试的对应关系为(B)。

A.甲-A,乙-B,丙-C
B.甲-A,乙-C,丙-B
C.甲-B,乙-A,丙-C
D.甲-B,乙-C,丙-A
E.甲-C,乙-A,丙-B
F.甲-C,乙-B,丙-A

例24.某机器人可以说真话或者假话。某程序设定其周末(周六周日)说真话,周四说谎话,其他日期随机。某测试打算验证该功能。他连续七天,每天问机器人“你在哪里出生的?”,在前六天得到了这样的答案:阿里,淘宝,阿里,淘宝,天猫,淘宝。那么第七天,机器人的回答应该是(A.)

A.阿里 B.淘宝 C.天猫 D.阿里或淘宝 E.阿里或天猫 F.天猫或淘宝

解析:因为答案中没有两个连续相同的,所以第一天只可能是周日或周一

假设第一天的周日,则第七天周六回答应该是周日的阿里,与周四的天猫假话对应,所以这种可能正确

假设第一天是周一,则第七天周日回答应该是周六的淘宝,与周四的淘宝假话冲突,所以这种可能错误

故第七天回答应该是阿里。

 

考点归纳:

1.数据结构(哈夫曼树、堆排序、后序遍历)

2.C基础(指针、地址、sizeof)

3.计算机网络(VPN、TCP/IP、局域网)

4.操作系统(进程线程、系统调用)

5.概率论

6.逻辑题

7.智力题

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