Java集训(算法&&面试题)第六天 (容器 & 库)

128 阅读3分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。

导读

在这里插入图片描述

在刚刚结束的 每日算法&面试题,大厂特训二十八天冲刺大厂每日算法&面试题,动态规划21天 的训练中我们一起打卡走了过来。但是学习不能停呀,从今天开始我们开始Java集训(算法&&面试题)第一天接着卷起来。

Java集训

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开头的元素 boolean empty() 如果队列为空,返回 true ;否则,返回 false 说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
初始化:
class MyQueue {

    public MyQueue() {

    }
    
    public void push(int x) {

    }
    
    public int pop() {

    }
    
    public int peek() {

    }
    
    public boolean empty() {

    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */


private int front;

public void push(int x) {
    if (s1.empty())
        front = x;
    while (!s1.isEmpty())
        s2.push(s1.pop());
    s2.push(x);
    while (!s2.isEmpty())
        s1.push(s2.pop());
}


// Removes the element from the front of queue.
public void pop() {
    s1.pop();
    if (!s1.empty())
        front = s1.peek();
}



// Return whether the queue is empty.
public boolean empty() {
    return s1.isEmpty();
}

// Get the front element.
public int peek() {
  return front;
}

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,1], k = 3
输出:true
示例 2:

输入:nums = [1,0,1,1], k = 1
输出:true
示例 3:

输入:nums = [1,2,3,1,2,3], k = 2
输出:false

思路:滑动窗口


class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Set<Integer> set = new HashSet<Integer>();
        int length = nums.length;
        for (int i = 0; i < length; i++) {
            if (i > k) {
                set.remove(nums[i - k - 1]);
            }
            if (!set.add(nums[i])) {
                return true;
            }
        }
        return false;
    }
}



面试题

Lambda 表达式是啥?优缺点?
lambda 表达式,也被称为闭包,它是推动 Java 8 发布的最重要新特性。lambda 允许把函
数作为一个方法的参数(函数作为参数传递进方法中),使用 Lambda 表达式可以使代码变
的更加简洁紧凑。
优点:
 代码更加简洁
 减少匿名内部类的创建,节省资源
 使用时不用去记忆所使用的接口和抽象函数
缺点:
 不易于后期维护,必须熟悉 lambda 表达式和抽象函数中参数的类型
 可读性差
 若不用并行计算,很多时候计算速度没有比传统的 for 循环快。(并行计算有时需要预热
才显示出效率优势)
 不容易调试。
 若其他程序员没有学过 lambda 表达式,代码不容易让其他语言的程序员看懂。


讲一下 Lambda 的表达式作用域(Lambda Scopes)。
访问局部变量
 我们可以直接在 lambda 表达式中访问外部的局部变量:但是和匿名对象不同的是,这里
的变量可以不用声明为 final,该代码同样正确,不过这里的变量必须不可被后面的代码
修改(即隐性的具有 final 的语义)
访问字段和静态变量
 与局部变量相比,我们对 lambda 表达式中的实例字段和静态变量都有读写访问权限。
该行为和匿名对象是一致的。
访问默认接口方法
 无法从 lambda 表达式中访问默认方法