Java八股文(数据结构)

news2024/9/21 10:38:19

Java八股文の数据结构

  • 数据结构

数据结构

  1. 请解释以下数据结构的概念:链表、栈、队列和树。

链表是一种线性数据结构,由节点组成,每个节点包含了指向下一个节点的指针;
栈是一种后进先出(LIFO)的数据结构,只能在一端进行插入和删除操作;
队列是一种先进先出(FIFO)的数据结构,一端进行插入操作,在另一端进行删除操作;
树是一种非线性数据结构,由节点和边组成,其中父节点可以有多个子节点。

  1. 请解释下面时间复杂度符号的含义:O(1)、O(log n)、O(n)和O(n^2)。

O(1)表示算法的执行时间不随输入规模变化;
O(log n)表示算法的执行时间随输入规模的增加而增加,但增加速度较慢;
O(n)表示算法的执行时间与输入规模成正比;
O(n^2)表示算法的执行时间与输入规模的平方成正比。

  1. 请解释什么是二分查找,并提供一个二分查找的实现。

二分查找是一种在有序数组中查找元素的算法,每次都将区间缩小为原来的一半,直到找到目标元素或无法再缩小。
以下是一个二分查找的实现(Java):

public int binarySearch(int[] arr, int target) {
    int left = 0;
    int right = arr.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}
  1. 请解释什么是哈希表,并提供一个哈希函数的示例。

哈希表是一种基于哈希函数的数据结构,用于存储和查找键值对。
哈希函数将键映射为一个固定大小的数组索引,使得在查找或插入时可以快速定位。
以下是一个哈希函数的示例(Java):

public int hashFunction(String key) {
    int hash = 0;
    for (int i = 0; i < key.length(); i++) {
        hash = (hash + key.charAt(i) - 'a') % tableSize;
    }
    return hash;
}

在此示例中,假设我们将英文字母映射为整数,'a’对应0,'b’对应1,以此类推。

  1. 请解释什么是二叉树,并提供一个二叉树的遍历实现(前序、中序和后序)。

二叉树是一种特殊的树结构,每个节点最多有两个子节点,称为左子节点和右子节点。
以下是二叉树的前序、中序和后序遍历的实现(Java):

// 前序遍历(根-左-右)
public void preOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    System.out.println(root.val);
    preOrderTraversal(root.left);
    preOrderTraversal(root.right);
}

// 中序遍历(左-根-右)
public void inOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    inOrderTraversal(root.left);
    System.out.println(root.val);
    inOrderTraversal(root.right);
}

// 后序遍历(左-右-根)
public void postOrderTraversal(TreeNode root) {
    if (root == null) {
        return;
    }
    postOrderTraversal(root.left);
    postOrderTraversal(root.right);
    System.out.println(root.val);
}

这里的TreeNode是二叉树的节点类,包含一个值val和左右子节点的引用。

  1. 请解释什么是图,并提供一种图的表示方法。

图是一种非线性数据结构,由节点(顶点)和边组成,表示顶点之间的关系。
常用的图的表示方法有邻接矩阵和邻接表。
邻接矩阵使用二维数组表示节点之间的连接关系,而邻接表则使用链表数组表示每个节点的邻居。

  1. 请解释什么是堆,并提供一个堆的实现。

堆是一种完全二叉树,分为最大堆和最小堆。
最大堆中,每个父节点的值都大于或等于其子节点的值;
最小堆中,每个父节点的值都小于或等于其子节点的值。
以下是一个最大堆的实现(Java):

class MaxHeap {
    private int[] heap;
    private int size;
    
    public MaxHeap(int capacity) {
        heap = new int[capacity];
        size = 0;
    }
    
    public void insert(int value) {
        if (size == heap.length) {
            throw new IllegalStateException("Heap is full");
        }
        
        heap[size] = value;
        siftUp(size);
        size++;
    }
    
    private void siftUp(int index) {
        while (index > 0 && heap[index] > heap[parentIndex(index)]) {
            swap(index, parentIndex(index));
            index = parentIndex(index);
        }
    }
    
    public int removeMax() {
        if (size == 0) {
            throw new IllegalStateException("Heap is empty");
        }
        
        int max = heap[0];
        heap[0] = heap[size - 1];
        size--;
        siftDown(0);
        return max;
    }
    
    private void siftDown(int index) {
        while (leftChildIndex(index) < size) {
            int maxIndex = leftChildIndex(index);
            if (rightChildIndex(index) < size && heap[rightChildIndex(index)] > heap[leftChildIndex(index)]) {
                maxIndex = rightChildIndex(index);
            }
            if (heap[index] >= heap[maxIndex]) {
                break;
            }
            swap(index, maxIndex);
            index = maxIndex;
        }
    }
    
    // Helper methods for calculating parent and child indices
    private int parentIndex(int index) {
        return (index - 1) / 2;
    }
    
    private int leftChildIndex(int index) {
        return 2 * index + 1;
    }
    
    private int rightChildIndex(int index) {
        return 2 * index + 2;
    }
    
    private void swap(int index1, int index2) {
        int temp = heap[index1];
        heap[index1] = heap[index2];
        heap[index2] = temp;
    }
}

该堆类提供了插入和删除最大值的操作,并保持了堆的性质。

  1. 请解释什么是哈夫曼树,并提供一个哈夫曼编码的实现。

哈夫曼树是一种用于数据编码的树结构,用于将频率较高的字符编码为较短的二进制码,以实现更高的压缩比。
哈夫曼编码的实现需要构建哈夫曼树,并通过DFS遍历树来生成每个字符的编码。
以下是一个哈夫曼编码的实现(Java):

class HuffmanNode implements Comparable<HuffmanNode> {
    char value;
    int frequency;
    HuffmanNode left;
    HuffmanNode right;
    
    public HuffmanNode(char value, int frequency) {
        this.value = value;
        this.frequency = frequency;
    }
    
    @Override
    public int compareTo(HuffmanNode other) {
        return this.frequency - other.frequency;
    }
}

public String huffmanEncode(String text) {
    if (text.isEmpty()) {
        return "";
    }
    
    // Calculate character frequencies
    Map<Character, Integer> frequencies = new HashMap<>();
    for (char c : text.toCharArray()) {
        frequencies.put(c, frequencies.getOrDefault(c, 0) + 1);
    }
    
    // Build Huffman tree
    PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();
    for (Map.Entry<Character, Integer> entry : frequencies.entrySet()) {
        pq.offer(new HuffmanNode(entry.getKey(), entry.getValue()));
    }
    while (pq.size() > 1) {
        HuffmanNode left = pq.poll();
        HuffmanNode right = pq.poll();
        HuffmanNode merged = new HuffmanNode('-', left.frequency + right.frequency);
        merged.left = left;
        merged.right = right;
        pq.offer(merged);
    }
    
    // Generate Huffman codes
    Map<Character, String> codes = new HashMap<>();
    generateCodes(pq.peek(), "", codes);
    
    // Encode the text
    StringBuilder encodedText = new StringBuilder();
    for (char c : text.toCharArray()) {
        encodedText.append(codes.get(c));
    }
    return encodedText.toString();
}

private void generateCodes(HuffmanNode node, String code, Map<Character, String> codes) {
    if (node == null) {
        return;
    }
    
    if (node.left == null && node.right == null) {
        codes.put(node.value, code);
    }
    
    generateCodes(node.left, code + "0", codes);
    generateCodes(node.right, code + "1", codes);
}

该示例中,huffmanEncode方法接受一个字符串,并返回其哈夫曼编码后的结果。

  1. 请解释深度优先搜索(DFS)和广度优先搜索(BFS)的区别。

DFS和BFS是两种图遍历的算法。
DFS以深度为优先,从起始节点开始,尽可能深入地访问其邻居节点,直到无法再深入为止,然后回溯到上一个节点。
BFS以广度为优先,从起始节点开始,依次访问同一层级的节点,再逐层向下一层级访问。
DFS适用于查找目标在树或图中的路径,而BFS适用于查找最短路径或查找目标在特定距离内的节点。

  1. 请解释什么是红黑树,并说明其性质。

红黑树是一种自平衡的二叉搜索树,具有以下性质:

● 每个节点是红色或黑色。
● 根节点是黑色。
● 每个叶子节点(NIL节点)是黑色。
● 如果一个节点是红色,则其子节点必须是黑色(不能有两个相邻的红色节点)。
● 从任一节点到其每个叶子的所有路径都包含相同数量的黑色节点。

  1. 请解释什么是AVL树,并说明其性质。

AVL树是一种自平衡的二叉搜索树,具有以下性质:

● 对于每个节点,其左子树和右子树的高度差(平衡因子)最多为1。
● 任意节点的左子树和右子树都是AVL树。

  1. 请解释什么是B树,并说明其特点。

B树是一种自平衡的多路搜索树,具有以下特点:

● 每个节点最多有M个子节点(M>=2)。
● 除根节点和叶子节点外,每个节点至少有M/2个子节点。
● 所有叶子节点都在同一层级上。

  1. 请解释什么是缓存淘汰策略,并提供两个常见的缓存淘汰策略。

缓存淘汰策略用于在缓存容量不足时确定哪些项目应从缓存中淘汰。
常见的缓存淘汰策略有:

● 最近最少使用(Least Recently Used, LRU):淘汰最近最少使用的项目,即最长时间未被访问的项目。
● 最不常用(Least Frequently Used, LFU):淘汰使用频率最低的项目,即被访问次数最少的项目。

  1. 请解释什么是拓扑排序,并提供一个拓扑排序的实现。

拓扑排序是一种对有向无环图进行排序的算法,使得所有边的方向均从前向后。
以下是一个拓扑排序的实现(Java):

public List<Integer> topologicalSort(int numCourses, int[][] prerequisites) {
    List<Integer> sortedOrder = new ArrayList<>();
    if (numCourses <= 0) {
        return sortedOrder;
    }

    // 1. 构建图和入度数组
    Map<Integer, List<Integer>> graph = new HashMap<>();
    int[] inDegree = new int[numCourses];
    for (int i = 0; i < numCourses; i++) {
        graph.put(i, new ArrayList<>());
    }
    for (int[] prerequisite : prerequisites) {
        int parent = prerequisite[1];
        int child = prerequisite[0];
        graph.get(parent).add(child);
        inDegree[child]++;
    }

    // 2. 将入度为0的节点加入队列
    Queue<Integer> queue = new LinkedList<>();
    for (int i = 0; i < numCourses; i++) {
        if (inDegree[i] == 0) {
            queue.offer(i);
        }
    }

    // 3. 逐个从队列取出节点,减少相关节点的入度并判断是否入队
    while (!queue.isEmpty()) {
        int node = queue.poll();
        sortedOrder.add(node);
        List<Integer> children = graph.get(node);
        for (int child : children) {
            inDegree[child]--;
            if (inDegree[child] == 0) {
                queue.offer(child);
            }
        }
    }

    // 4. 判断是否存在环
    if (sortedOrder.size() != numCourses) {
        return new ArrayList<>();
    }
    return sortedOrder;
}

该方法接受课程数量和先修关系的二维数组,并返回一个拓扑有序的课程列表。

  1. 请解释什么是并查集,并提供一个并查集的实现。

并查集是一种用于解决集合合并和查询的数据结构,支持以下两种操作:

● 查找(Find):确定元素所属的集合。
● 合并(Union):将两个集合合并为一个集合。
以下是一个并查集的实现(Java):

class UnionFind {
    private int[] parent;
    private int[] rank;
    
    public UnionFind(int size) {
        parent = new int[size];
        rank = new int[size];
        for (int i = 0; i < size; i++) {
            parent[i] = i;
            rank[i] = 0;
        }
    }
    
    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }
    
    public void union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            if (rank[rootX] < rank[rootY]) {
                parent[rootX] = rootY;
            } else if (rank[rootX] > rank[rootY]) {
                parent[rootY] = rootX;
            } else {
                parent[rootY] = rootX;
                rank[rootX]++;
            }
        }
    }
}

该并查集类提供了查找和合并操作,并使用路径压缩和按秩合并的优化策略。

  1. 请解释什么是动态规划,并提供一个使用动态规划解决的问题示例。

动态规划(Dynamic Programming,简称DP)是一种解决多阶段决策最优化问题的方法。
它将问题划分为若干个子问题,并保存子问题的解来避免重复计算。
通过递推求解各个子问题,最终得到原问题的解。
一个典型的动态规划问题是求解最长公共子序列(Longest Common Subsequence,简称LCS)。
给定两个字符串s1和s2,求它们的最长公共子序列的长度。
示例:

public class LongestCommonSubsequence {
    public int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length();
        int n = text2.length();
        int[][] dp = new int[m + 1][n + 1]; // dp[i][j]表示text1前i个字符和text2前j个字符的最长公共子序列长度
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1; // 当前字符相等,最长公共子序列长度加1
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); // 当前字符不相等,取前一步的最优解
                }
            }
        }
        
        return dp[m][n];
    }
}

在这个示例中,使用动态规划求解了最长公共子序列的长度。
通过定义一个二维数组dp,其中dp[i][j]表示text1前i个字符和text2前j个字符的最长公共子序列长度。
在遍历字符串text1和text2时,根据字符是否相等来更新dp数组的值。
最终返回dp[m][n]即为最长公共子序列的长度。
动态规划的思想可以帮助我们高效地解决很多复杂的问题,包括字符串匹配、最短路径、背包问题等。

  1. 实现一个二叉树的前序遍历算法。
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    
    public TreeNode(int val) {
        this.val = val;
    }
}

public class PreorderTraversal {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        if (root == null) {
            return result;
        }
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.right != null) {
                stack.push(node.right);
            }
            if (node.left != null) {
                stack.push(node.left);
            }
        }
        return result;
    }
}
  1. 实现一个队列,并实现基本的操作:入队、出队、获取队首元素。
class MyQueue {
    private Stack<Integer> inStack;
    private Stack<Integer> outStack;
    
    public MyQueue() {
        inStack = new Stack<>();
        outStack = new Stack<>();
    }
    
    public void push(int x) {
        inStack.push(x);
    }
    
    public int pop() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.pop();
    }
    
    public int peek() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.peek();
    }
    
    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }
}
  1. 实现一个栈,并实现基本的操作:入栈、出栈、获取栈顶元素、判断栈是否为空。
class MyStack {
    private Deque<Integer> stack;
    
    public MyStack() {
        stack = new LinkedList<>();
    }
    
    public void push(int x) {
        stack.push(x);
    }
    
    public int pop() {
        return stack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public boolean empty() {
        return stack.isEmpty();
    }
}
  1. 实现一个链表的反转。
class ListNode {
    int val;
    ListNode next;
    
    public ListNode(int val) {
        this.val = val;
    }
}

public class ReverseLinkedList {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) {
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}
  1. 实现一个图的深度优先搜索(DFS)算法。
import java.util.ArrayList;
import java.util.List;

class Graph {
    private int V;
    private List<List<Integer>> adj;
    
    public Graph(int V) {
        this.V = V;
        adj = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
    }
    
    public void addEdge(int u, int v) {
        adj.get(u).add(v);
    }
    
    public void DFS(int v) {
        boolean[] visited = new boolean[V];
        DFSUtil(v, visited);
    }
    
    private void DFSUtil(int v, boolean[] visited) {
        visited[v] = true;
        System.out.print(v + " ");
        for (int i : adj.get(v)) {
            if (!visited[i]) {
                DFSUtil(i, visited);
            }
        }
    }
}
  1. 实现一个图的广度优先搜索(BFS)算法。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

class Graph {
    private int V;
    private List<List<Integer>> adj;
    
    public Graph(int V) {
        this.V = V;
        adj = new ArrayList<>(V);
        for (int i = 0; i < V; i++) {
            adj.add(new ArrayList<>());
        }
    }
    
    public void addEdge(int u, int v) {
        adj.get(u).add(v);
    }
    
    public void BFS(int v) {
        boolean[] visited = new boolean[V];
        Queue<Integer> queue = new LinkedList<>();
        visited[v] = true;
        queue.offer(v);
        
        while (!queue.isEmpty()) {
            int curr = queue.poll();
            System.out.print(curr + " ");
            for (int i : adj.get(curr)) {
                if (!visited[i]) {
                    visited[i] = true;
                    queue.offer(i);
                }
            }
        }
    }
}
  1. 实现一个最小堆。
class MinHeap {
    private int[] heap;
    private int size;
    
    public MinHeap(int capacity) {
        heap = new int[capacity];
        size = 0;
    }
    
    public void insert(int key) {
        if (size == heap.length) {
            // 堆已满
            return;
        }
        size++;
        int i = size - 1;
        heap[i] = key;
        
        while (i > 0 && heap[parent(i)] > heap[i]) {
            // 交换节点值
            swap(i, parent(i));
            i = parent(i);
        }
    }
    
    public void delete(int key) {
        int index = -1;
        for (int i = 0; i < size; i++) {
            if (heap[i] == key) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            // 不存在该元素
            return;
        }
        decreaseKey(index, Integer.MIN_VALUE);
        extractMin();
    }
    
    public int extractMin() {
        if (size == 0) {
            return Integer.MIN_VALUE;
        }
        if (size == 1) {
            size--;
            return heap[0];
        }
        int root = heap[0];
        heap[0] = heap[size - 1];
        size--;
        minHeapify(0);
        return root;
    }
    
    private void decreaseKey(int i, int newValue) {
        heap[i] = newValue;
        while (i != 0 && heap[parent(i)] > heap[i]) {
            swap(i, parent(i));
            i = parent(i);
        }
    }
    
    private void minHeapify(int i) {
        int smallest = i;
        int left = leftChild(i);
        int right = rightChild(i);
        
        if (left < size && heap[left] < heap[smallest]) {
            smallest = left;
        }
        
        if (right < size && heap[right] < heap[smallest]) {
            smallest = right;
        }
        
        if (smallest != i) {
            swap(i, smallest);
            minHeapify(smallest);
        }
    }
    
    private int parent(int i) {
        return (i - 1) / 2;
    }
    
    private int leftChild(int i) {
        return 2 * i + 1;
    }
    
    private int rightChild(int i) {
        return 2 * i + 2;
    }
    
    private void swap(int i, int j) {
        int temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
}
  1. 实现一个哈希表。
class MyHashMap {
    private final int SIZE = 10000;
    private ListNode[] table;
    
    class ListNode {
        int key;
        int value;
        ListNode next;
        
        public ListNode(int key, int value) {
            this.key = key;
            this.value = value;
            this.next = null;
        }
    }
    
    public MyHashMap() {
        table = new ListNode[SIZE];
    }
    
    public void put(int key, int value) {
        int index = getIndex(key);
        if (table[index] == null) {
            table[index] = new ListNode(-1, -1);
        }
        ListNode prev = findElement(table[index], key);
        if (prev.next == null) {
            prev.next = new ListNode(key, value);
        } else {
            prev.next.value = value;
        }
    }
    
    public int get(int key) {
        int index = getIndex(key);
        if (table[index] == null) {
            return -1;
        }
        ListNode prev = findElement(table[index], key);
        if (prev.next == null) {
            return -1;
        }
        return prev.next.value;
    }
    
    public void remove(int key) {
        int index = getIndex(key);
        if (table[index] == null) {
            return;
        }
        ListNode prev = findElement(table[index], key);
        if (prev.next == null) {
            return;
        }
        prev.next = prev.next.next;
    }
    
    private int getIndex(int key) {
        return Integer.hashCode(key) % SIZE;
    }
    
    private ListNode findElement(ListNode bucket, int key) {
        ListNode prev = null;
        ListNode curr = bucket;
        while (curr != null && curr.key != key) {
            prev = curr;
            curr = curr.next;
        }
        return prev;
    }
}
  1. 实现一个动态数组。
class DynamicArray {
    private int[] array;
    private int size;
    private int capacity;
    
    public DynamicArray() {
        array = new int[10];
        size = 0;
        capacity = 10;
    }
    
    public void add(int value) {
        if (size == capacity) {
            expandCapacity();
        }
        array[size] = value;
        size++;
    }
    
    public int get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        return array[index];
    }
    
    public void set(int index, int value) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        array[index] = value;
    }
    
    public int size() {
        return size;
    }
    
    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        for (int i = index; i < size - 1; i++) {
            array[i] = array[i + 1];
        }
        size--;
    }
    
    private void expandCapacity() {
        int newCapacity = capacity * 2;
        int[] newArray = new int[newCapacity];
        for (int i = 0; i < capacity; i++) {
            newArray[i] = array[i];
        }
        capacity = newCapacity;
        array = newArray;
    }
}
  1. 实现一个有序数组的二分查找。
class BinarySearch {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return -1;
    }
}
  1. 实现一个字符串的反转。
class StringReverse {
    public String reverse(String s) {
        char[] chars = s.toCharArray();
        int left = 0;
        int right = chars.length - 1;
        while (left < right) {
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
        return new String(chars);
    }
}
  1. 实现一个队列的使用两个栈来模拟。
class MyQueue {
    private Stack<Integer> inStack;
    private Stack<Integer> outStack;
    
    public MyQueue() {
        inStack = new Stack<>();
        outStack = new Stack<>();
    }
    
    public void push(int x) {
        inStack.push(x);
    }
    
    public int pop() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.pop();
    }
    
    public int peek() {
        if (outStack.isEmpty()) {
            while (!inStack.isEmpty()) {
                outStack.push(inStack.pop());
            }
        }
        return outStack.peek();
    }
    
    public boolean empty() {
        return inStack.isEmpty() && outStack.isEmpty();
    }
}
  1. 实现一个栈的使用两个队列来模拟。
class MyStack {
    private Queue<Integer> inQueue;
    private Queue<Integer> outQueue;
    
    public MyStack() {
        inQueue = new LinkedList<>();
        outQueue = new LinkedList<>();
    }
    
    public void push(int x) {
        inQueue.offer(x);
        while (!outQueue.isEmpty()) {
            inQueue.offer(outQueue.poll());
        }
        Queue<Integer> temp = inQueue;
        inQueue = outQueue;
        outQueue = temp;
    }
    
    public int pop() {
        return outQueue.poll();
    }
    
    public int top() {
        return outQueue.peek();
    }
    
    public boolean empty() {
        return outQueue.isEmpty();
    }
}
  1. 实现一个判断链表中是否有环的算法。
class ListNode {
    int val;
    ListNode next;
    
    public ListNode(int val) {
        this.val = val;
        this.next = null;
    }
}

class LinkedListCycle {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast) {
                return true;
            }
        }
        return false;
    }
}

内容来自
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1553117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【教学类-35-20】20240328 中4班描字帖(学号+姓名 A4竖版2份 横面)+裁剪纸条+插入式纸盒

作品展示 背景需求&#xff1a; 整理仓库&#xff0c;找到之前打印的另外一套灰色版的学号字体&#xff08;和2月20日那份一模一样&#xff09; 【教学类-35-19】20240117 中4班描字帖&#xff08;学号姓名 A4竖版2份 横面&#xff09;-CSDN博客文章浏览阅读571次&#xff0c;…

Mysql数据库-DQL查询

Mysql数据库-DQL基本查询 1 DQL基本查询1.1 基础查询1.2 WHERE子句1&#xff09;算术运算符2&#xff09;逻辑运算符3&#xff09;比较运算符A&#xff09;BETWEEN... AND ...B&#xff09;IN(列表)C&#xff09;NULL值判断 4&#xff09;综合练习 2 DQL高级查询2.1 LIKE 模糊查…

SAP-CO主数据之统计指标创建-<KK01>

公告&#xff1a;周一至周五每日一更&#xff0c;周六日存稿&#xff0c;请您点“关注”和“在看”&#xff0c;后续推送的时候不至于看不到每日更新内容&#xff0c;感谢。 目录 一、背景&#xff1a; 成本中心主数据创建&#xff1a;传送门 成本要素主数据创建&#xff1…

人工智能(pytorch)搭建模型26-基于pytorch搭建胶囊模型(CapsNet)的实践,CapsNet模型结构介绍

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型26-基于pytorch搭建胶囊模型(CapsNet)的实践&#xff0c;CapsNet模型结构介绍。CapsNet&#xff08;Capsule Network&#xff09;是一种创新的深度学习模型&#xff0c;由计算机科学家Geo…

Linux——信号的保存与处理

目录 前言 一、信号的常见概念 1.信号递达 2.信号未决 3.信号阻塞 二、Linux中的递达未决阻塞 三、信号集 四、信号集的处理 1.sig相关函数 2.sigprocmask()函数 3.sigpending()函数 五、信号的处理时机 六、信号处理函数 前言 在之前&#xff0c;我们学习了信号…

未发TOKEN的Scroll除了撸毛还能如何获取机会?来Penpad Season 2,享受一鱼多吃!

Penpad 是 Scroll 上的 LauncPad 平台&#xff0c;该平台继承了 Scroll 底层的技术优势&#xff0c;并基于零知识证明技术&#xff0c;推出了系列功能包括账户抽象化、灵活的挖矿功能&#xff0c;并将在未来实现合规为 RWA 等资产登录 Scroll 生态构建基础。该平台被认为是绝大…

STM32时钟简介

1、复位&#xff1a;使时钟恢复原始状态 就是将寄存器状态恢复到复位值 STM32E10xxx支持三种复位形式,分别为系统复位、上电复位和备份区域复位。 复位分类&#xff1a; 1.1系统复位 除了时钟控制器的RCC_CSR寄存器中的复位标志位和备份区域中的寄存器以外,系统 复位将复位…

Python学习:lambda(匿名函数)、装饰器、数据结构

Python Lambda匿名函数 Lambda函数&#xff08;或称为匿名函数&#xff09;是Python中的一种特殊函数&#xff0c;它可以用一行代码来创建简单的函数。Lambda函数通常用于需要一个函数作为输入的函数&#xff08;比如map()&#xff0c;filter()&#xff0c;sort()等&#xff0…

fast_bev学习笔记

目录 一. 简述二. 输入输出三. github资源四. 复现推理过程4.1 cuda tensorrt 版 一. 简述 原文:Fast-BEV: A Fast and Strong Bird’s-Eye View Perception Baseline FAST BEV是一种高性能、快速推理和部署友好的解决方案&#xff0c;专为自动驾驶车载芯片设计。该框架主要包…

ssm婚纱摄影管理系统的设计+1.2w字论文+免费调试

项目演示视频&#xff1a; ssm婚纱摄影管理系统的设计 项目介绍: 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“婚纱摄影网的设计”&#xff0c;这样就让婚纱摄影网的设计更…

IDEA跑Java后端项目提示内存溢出

要设置几个地方&#xff0c;都试一下吧&#xff1a; 1、默认是700&#xff0c;我们设置大一点&#xff08;上次配置了这儿就解决了&#xff09; 2、 3、 4、-Xmx4g

Linux基础命令篇:文本处理命令基础操作(awk、sed、sort、uniq、wc)

Linux基础命令之文件处理 1. awk awk是一种文本处理工具&#xff0c;用于处理结构化文本数据。它基于模式匹配和动作来处理输入数据。以下是一些常用的awk选项和示例&#xff1a; 1.1- 打印指定字段&#xff1a;awk { print $1, $3 } input-file&#xff08;打印输入文件中的…

【YOLOv5改进系列(6)】高效涨点----使用DAMO-YOLO中的Efficient RepGFPN模块替换yolov5中的Neck部分

文章目录 &#x1f680;&#x1f680;&#x1f680;前言一、1️⃣ 添加yolov5_GFPN.yaml文件二、2️⃣添加extra_modules.py代码三、3️⃣yolo.py文件添加内容3.1 &#x1f393; 添加CSPStage模块 四、4️⃣实验结果4.1 &#x1f393; 使用yolov5s.pt训练的结果对比4.2 ✨ 使用…

Javascript 数字精度丢失的问题(超级详细的讲解)

文章目录 一、场景复现二、浮点数二、问题分析小结 三、解决方案参考文献 一、场景复现 一个经典的面试题 0.1 0.2 0.3 // false为什么是false呢? 先看下面这个比喻 比如一个数 130.33333333… 3会一直无限循环&#xff0c;数学可以表示&#xff0c;但是计算机要存储&a…

Linux下iptables实战指南:Ubuntu 22.04安全配置全解析

Linux下iptables实战指南&#xff1a;Ubuntu 22.04安全配置全解析 引言iptables基础知识工作原理组件介绍 iptables规则管理添加规则修改规则删除规则规则持久化 常见的iptables应用场景防止DDoS攻击限制访问速率端口转发日志管理 高级配置和技巧基于时间的规则基于用户的规则结…

语音模块摄像头模块阿里云结合,实现垃圾的智能识别

语音模块&摄像头模块&阿里云结合 文章目录 语音模块&摄像头模块&阿里云结合1、实现的功能2、配置2.1 软件环境2.2 硬件配置 3、程序介绍3.1 程序概况3.2 语言模块SDK配置介绍3.3 程序文件3.3.1 开启摄像头的程序3.3.2 云端识别函数( Py > C ) & 串口程序…

【实现报告】学生信息管理系统(顺序表)

目录 实验一 线性表的基本操作 一、实验目的 二、实验内容 三、实验提示 四、实验要求 五、实验代码如下&#xff1a; &#xff08;一&#xff09;顺序表的构建及初始化 &#xff08;二&#xff09;检查顺序表是否需要扩容 &#xff08;三&#xff09;根据指定学生个…

Redis命令-List命令

4.6 Redis命令-List命令 Redis中的List类型与Java中的LinkedList类似&#xff0c;可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。 特征也与LinkedList类似&#xff1a; 有序元素可以重复插入和删除快查询速度一般 常用来存储一个有序数据&#xff…

工控安全双评合规:等保测评与商用密码共铸新篇章

01.双评合规概述 2017年《中华人民共和国网络安全法》开始正式施行&#xff0c;网络安全等级测评工作也在全国范围内按照相关法律法规和技术标准要求全面落实实施。2020年1月《中华人民共和国密码法》开始正式施行&#xff0c;商用密码应用安全性评估也在有序推广和逐步推进。…

Day60-Nginx反向代理与负载均衡基于URI及USER_AGENT等跳转讲解

Day60-Nginx反向代理与负载均衡基于URI及USER_AGENT等跳转讲解 9. 基于uri实现动静分离、业务模块分离调度企业案例&#xff08;参考书籍&#xff09;10.基于user_agent及浏览器实现转发(参考书籍)11.根据文件扩展名实现代理转发12. Nginx负载均衡监测节点状态13.proxy_next_up…