4/26腾讯笔试复盘

1、完成队列的PUSH,POP,TOP,SIZE,CLEAR操作。只有POP,TOP,SIZE有输出操作,其中POP只有在没有元素时输出-1,其他情况不输出;TOP在没有元素时输出-1

    输入: 2                    次数n
               4                    每次m个操作,且每次队列置空
               PUSH 1          第i次操作
               PUSH 2
               PUSH 3
               TOP
               5
               SIZE
               PUSH 2
               TOP
               POP
               TOP
    输出: 1
               0
               2
              -1

import java.util.*;

public class Main{

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            int m = Integer.parseInt(sc.nextLine());
            queue.clear();
            for (int j = 0; j < m; j++) {
                String[] ss = sc.nextLine().split(" ");
                if(ss[0].equals("POP")){
                    if(queue.isEmpty()){
                        System.out.println(-1);
                    }
                }
                else if(ss[0].equals("TOP")){
                    System.out.println(queue.isEmpty()?-1:queue.peek());
                }
                else if(ss[0].equals("SIZE")){
                    System.out.println(queue.size());
                }
                else if(ss[0].equals("PUSH")){
                    queue.offer(Integer.valueOf(ss[1]));
                }
                else if(ss[0].equals("CLEAR")){
                    queue.clear();
                }
            }
        }
    }
}

 

2、寻找两个点集中最近的对

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
    经典的分治算求平面中的最近点对的变形,唯一的区别是需要记录点是属于哪个阵营中。
    先将平面中的点按x坐标值排序,找到中间点mid,递归的在左右两侧找距离最小的点对距离min,再按照y坐标值排序,在中间点mid左右不超过min的点,对于每个点只需与它之后的六个点进行比较,找到中间区域的最小值tempmin,与min相比较得到min的最终值
    时间复杂度为O(nlogn),空间复杂度O(n)

import java.util.*;

public class Main{
    static class Node{
        double x,y;
        int f;
    }
    public static double cal(Node x,Node y){
        if(x.f == y.f){
            return Double.MAX_VALUE;
        }
        return Math.sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
    }
    public static double mergeSort(Node[] nodes,int left,int right){
        double min = Double.MAX_VALUE;
        if(right-left <= 0){
            return min;
        }
        if(right-left == 1){
            return cal(nodes[left],nodes[right]);
        }
        int mid = left+(right-left)/2;
        double mina = mergeSort(nodes,left,mid);
        double minb = mergeSort(nodes,mid+1,right);
        min = mina > minb ? minb : mina;
        merge(nodes,left,mid,right);
        Node[] temps = new Node[right-left+1];
        int num = 0;
        for (int i = left; i <= right; i++) {
            if(Math.abs(nodes[i].x-nodes[mid].x) <= min){
                temps[num++] = nodes[i];
            }
        }
        double tempmin;
        for (int i = 0; i < num; i++) {
            for (int j = i+1; j < num && j < i+7; j++) {
                tempmin = cal(nodes[i],nodes[j]);
                if(tempmin < min){
                    min = tempmin;
                }
            }
        }
        return min;
    }
    public static void merge(Node[] nodes,int left,int mid,int right){
        Node[] temp = new Node[right-left+1];
        int j = left;
        int k = mid+1;
        int t = 0;
        while(j <= mid && k <= right){
            if(nodes[j].y < nodes[k].y){
                temp[t++] = nodes[j++];
            }
            else{
                temp[t++] = nodes[k++];
            }
        }
        while(j <= mid){
            temp[t++] = nodes[j++];
        }
        while(k <= right){
            temp[t++] = nodes[k++];
        }
        t = 0;
        while(left <= right){
            nodes[left++] = temp[t++];
        }
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        String[] ss = new String[2];
        for (int i = 0; i < n; i++) {
            int m = Integer.parseInt(sc.nextLine());
            Node[] nodes = new Node[2*m];
            for (int j = 0; j < m; j++) {
                ss = sc.nextLine().split(" ");
                Node node = new Node();
                node.x = Double.valueOf(ss[0]);
                node.y = Double.valueOf(ss[1]);
                node.f = 0;
                nodes[j] = node;
            }
            for (int j = m; j < 2*m; j++) {
                ss = sc.nextLine().split(" ");
                Node node = new Node();
                node.x = Double.valueOf(ss[0]);
                node.y = Double.valueOf(ss[1]);
                node.f = 1;
                nodes[j] = node;
            }
            Arrays.sort(nodes,(v1,v2)-> (int) (v1.x-v2.x));
            System.out.println(String.format("%.3f",mergeSort(nodes,0,2*m-1)));
        }
    }
}

 

4、两个栈实现队列

在这里插入图片描述
在这里插入图片描述
(1)用两个栈模拟队列,一个栈模拟入队列,一个栈模拟出队列;push()的时间复杂度为O(1),pop()的摊分时间复杂度为O(1),这是最巧妙的一种方法
(2)若存在不合法情况比如队列为空时进行pop()、peek()操作时,要进行判空;定义一个全局变量size,只有size != 0时,才进行pop()、peek()操作
(3)peek()操作的巧妙方法在于,在push()时,记录front值;如果stack2不为空,就return stack2.pop(),否则的话return front
(4)四个操作的时间复杂度都为O(1)

import java.util.*;

public class Main{
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    int size = 0;
    int front = 0;

    public Main() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }

    public void push(int x) {
        if(stack1.empty()){
            front = x;
        }
        stack1.push(x);
        size++;
    }

    public int pop() {
        if(size == 0){
            return -1;
        }
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.pop());
            }
        }
        size--;
        return stack2.pop();
    }

    public int peek() {
        if(!stack2.empty()){
            return stack2.peek();
        }
        return front;
    }

    public boolean empty() {
        return size==0?true:false;
    }
}

5、一棵无限深的的满二叉树,求x的k层祖先

  输入 : 4              次数n
             10 1          结点值  层数i
             10 2
             10 3
             10 4
  输出: 1               第i层祖先
             2
             5
            -1
(1)具有n个结点的完全二叉树,树的高度为log(n)+1,其中log(n)为向下取整;Java中向上取整的API是Math.ceil(double a),向下取整的API是Math.floor(double a),此题可直接用Math.getExponent()+1获得树的高度,因为Math.getExponent()是无偏指数且向下取整
(2)x的k层祖先可由x/2获得,循环的次数为x所在层数减去k

import java.util.*;

public class Main{

    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.nextLine());
        for (int j = 0; j < n; j++) {
            String[] ss = sc.nextLine().split(" ");
            int p = Integer.valueOf(ss[0]);
            int q = Integer.valueOf(ss[1]);
            if((Math.getExponent(p)+1) > q){
                int sum = Math.getExponent(p)+1-q;
                while(sum > 0){
                    p = p/2;
                    sum--;
                }
                System.out.println(p);
            }
            else{
                System.out.println(-1);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值