数据结构常见面试题及详细java示例

这篇具有很好参考价值的文章主要介绍了数据结构常见面试题及详细java示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

下面是一些常见的数据结构面试题以及使用Java实现的解决方案。

1、如何在给定数组中找到重复的元素?

        使用HashSet是一个常见的解决方法。

public class FindDuplicates {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 1, 2, 4};
        Set<Integer> set = new HashSet<>();

        for (int num : array) {
            if (!set.add(num)) {
                System.out.println("重复的元素是:" + num);
            }
        }
    }
}

2、链表反转

        反转链表是最常见的数据结构问题之一。以下是用Java实现的一个例子。

class ListNode {
      int val;
      ListNode next;
      ListNode() {}
      ListNode(int val) { this.val = val; }
      ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}

public class ReverseLinkedList {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode current = head;
        while (current != null) {
            ListNode nextTemp = current.next;
            current.next = prev;
            prev = current;
            current = nextTemp;
        }
        return prev;
    }
}

3、二叉树的深度

       这个问题可以使用递归来解决。

class TreeNode {
      int val;
      TreeNode left;
      TreeNode right;
      TreeNode(int x) { val = x; }
}

public class Solution {
    public int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        else {
            int leftHeight = maxDepth(root.left);
            int rightHeight = maxDepth(root.right);
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }
}

4、如何在给定数组中找到缺失的数?

        我们可以使用异或来找到缺失的数字,因为异或操作满足交换律和结合律。

public class MissingNumber {
    public static int findMissingNumber(int[] arr) {
        int n = arr.length;
        int x1 = arr[0];
        int x2 = 1;
        
        for (int i = 1; i < n; i++) {
            x1 = x1 ^ arr[i];
        }
        
        for (int i = 2; i <= n + 1; i++) {
            x2 = x2 ^ i;
        }
        
        return x1 ^ x2;
    }
    
    public static void main(String[] args) {
        int[] arr = {1, 2, 4, 6, 3, 7, 8};
        System.out.println("Missing number: " + findMissingNumber(arr));
    }
}

5、如何实现一个队列使用两个栈?

public class QueueWithTwoStacks {
    private Stack<Integer> s1 = new Stack<Integer>();
    private Stack<Integer> s2 = new Stack<Integer>();

    public void enqueue(int item) {
        s1.push(item);
    }

    public int dequeue() {
        if (s2.isEmpty()) {
            while (!s1.isEmpty()) {
                s2.push(s1.pop());
            }
        }
        return s2.pop();
    }
}

6、如何从链表中删除倒数第n个节点?

        这种问题可以通过快慢指针来解决。

public class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode fast = dummy;
        ListNode slow = dummy;

        for (int i = 1; i <= n + 1; i++) {
            fast = fast.next;
        }

        while (fast != null) {
            fast = fast.next;
            slow = slow.next;
        }

        slow.next = slow.next.next;

        return dummy.next;
    }
}

7、如何检查字符串中的括号是否正确配对?

        这是一个典型的利用栈数据结构来处理的问题。当遇到左括号时,我们把它压入栈中,当遇到右括号时,我们检查栈是否为空以及栈顶的左括号是否与之配对,如果配对则弹出栈顶元素,最后栈应该是空的。

public boolean isValid(String s) {
    Stack<Character> stack = new Stack<Character>();
    for (char c : s.toCharArray()) {
        if (c == '(')
            stack.push(')');
        else if (c == '[')
            stack.push(']');
        else if (c == '{')
            stack.push('}');
        else if (stack.isEmpty() || stack.pop() != c)
            return false;
    }
    return stack.isEmpty();
}

8、如何从给定数组中找到前k大的元素?

        这个问题可以用优先队列实现。Java里的优先队列用的是堆排序。

public List<Integer> findTopK(int[] nums, int k) {
    PriorityQueue<Integer> pq = new PriorityQueue<>(); // 小顶堆
    for (int val : nums) {
        pq.add(val);
        if (pq.size() > k)  // 如果加入后大小超过k,则队头元素出队
            pq.poll();
    }
    List<Integer> res = new ArrayList<>(pq);
    Collections.sort(res, Collections.reverseOrder());  // 降序排列
    return res;
}

9、二叉树的层次遍历

        这个问题可以通过使用队列进行广度优先遍历(BFS)来解决。

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> levels = new ArrayList<List<Integer>>();
    if (root == null) return levels;

    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.add(root);

    while (!queue.isEmpty()) {
        List<Integer> level = new ArrayList<Integer>();
        int levelSize = queue.size();
        for (int i = 0; i < levelSize; ++i) {
            TreeNode node = queue.remove();
            level.add(node.val);
            if (node.left != null) queue.add(node.left);
            if (node.right != null) queue.add(node.right);
        }
        levels.add(level);
    }
    return levels;
}

10、合并K个有序链表

        这个问题可以通过优先队列来解决,通过逐一比较链表的节点(最小堆)。

public class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        PriorityQueue<ListNode> queue = new PriorityQueue<>(Comparator.comparingInt(l -> l.val));
        ListNode dummy = new ListNode(0);
        ListNode curr = dummy;
        
        for (ListNode node : lists) {
            if (node!= null) {
                queue.add(node);
            }      
        }
        
        while (!queue.isEmpty()) {
            curr.next = queue.poll();
            curr = curr.next;
            if (curr.next != null) {
                queue.add(curr.next);
            }
        }
        return dummy.next;
    }
}

11、二叉树中的最大路径和

        这类问题可以使用分治的思想,通过递归来解决。

class Solution {
    int max_sum = Integer.MIN_VALUE;

    public int max_gain(TreeNode node) {
        if (node == null) return 0;

        // 递归计算左右子节点的最大贡献值
        // 只有在贡献值大于 0 时,才会选取对应子节点
        int left_gain = Math.max(max_gain(node.left), 0);
        int right_gain = Math.max(max_gain(node.right), 0);

        // 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
        int price_newpath = node.val + left_gain + right_gain;

        // 更新答案
        max_sum = Math.max(max_sum, price_newpath);

        // 返回节点的最大贡献值
        return node.val + Math.max(left_gain, right_gain);
    }

    public int maxPathSum(TreeNode root) {
        max_gain(root);
        return max_sum;
    }
}

12、找到数组中第K个最大的元素

        这种题目可以通过快速选择来解决,这是基于快速排序的一种优化算法。文章来源地址https://www.toymoban.com/news/detail-848712.html

class Solution {
    public int findKthLargest(int[] nums, int k) {
        k = nums.length - k; // convert it to 'kth smallest'
        int lo = 0; 
        int hi = nums.length - 1;
        while (lo < hi) {
            final int j = partition(nums, lo, hi);
            if(j < k) {
                lo = j + 1;
            } else if (j > k) {
                hi = j - 1;
            } else {
                break;
            }
        }
        return nums[k];
    }

    private int partition(int[] a, int lo, int hi) {
        int i = lo;
        int j = hi + 1;
        while(true) {
            while(a[++i] < a[lo] && i < hi);
            while(a[--j] > a[lo] && j > lo);
            if(i >= j) {
                break;
            }
            swap(a, i, j);
        }
        swap(a, lo, j);
        return j;
    }

    private void swap(int[] a, int i, int j) {
        final int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }  
}

到了这里,关于数据结构常见面试题及详细java示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot常见面试题汇总(超详细回答)

    Spring Boot 是一个基于 Spring 框架的开源框架,用于快速创建独立的、生产级别的、可运行的 Spring 应用程序。它采用了约定优于配置的理念,使开发者可以不需要手动配置大量的 Spring 配置文件,而快速搭建出符合生产要求的、可运行的应用程序。 Spring Boot 通过自动配置,可以

    2024年01月18日
    浏览(27)
  • 【数据结构】链表面试题

    203.移除链表元素 206.反转链表 876.链表的中间结点 牛客.链表中倒数第k个结点 21.合并两个有序链表 牛客.链表分隔 牛客.链表的回文结构 160.相交链表 141.环形链表 142.环形链表2 定义一个指针cur遍历整个链表,一个tail指针,cur遍历整个链表,如果cur-val!=val,就把tail的next存放cur指

    2024年02月08日
    浏览(28)
  • Java数据结构之排序(头歌平台,详细注释)

    目录 第1关:选择排序 任务描述 相关知识 代码:    第2关:插入排序 任务描述 相关知识 插入排序 代码:   第3关:归并排序 任务描述 相关知识 归并排序 原理 代码:    第4关:快速排序 任务描述 相关知识 快速排序 代码:    第5关:堆排序 任务描述 相关知识 堆

    2024年01月19日
    浏览(33)
  • 【数据结构】单链表面试题讲解->贰

    单链表的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于链表的应用题目,马上要进行秋招了。希望对你们有帮助 _ 😀 将两个升序链表合并为一个新的 升序 链表并返回。 新链表是通过拼接给定的两个链表的所有节点组成的。 🚩建立虚拟节

    2024年02月12日
    浏览(46)
  • 【数据结构】 单链表面试题讲解->壹

    单链表的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于链表的应用题目,马上要进行秋招了。希望对你们有帮助 _ 😀 给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

    2024年02月11日
    浏览(33)
  • 【数据结构】 单链表面试题讲解->叁

    🌏引言 单链表的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于链表的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点

    2024年02月11日
    浏览(50)
  • Java 数据结构之栈、队列(头歌平台,详细注释)

    目录 第1关:实现基于数组的 任务描述 相关知识 栈 栈的数组表示 Java 泛型简介 泛型方法 泛型类应用场景示例 代码:  第2关:实现基于链表的栈 任务描述 相关知识 栈的链式存储 入栈 出栈 代码:  第3关:基于数组的队列 任务描述 相关知识 队列 队列的数组实现 循环队列

    2024年04月25日
    浏览(32)
  • 【数据结构练习】链表面试题集锦一

    目录 前言: 1. 删除链表中所有值为key的节点  方法一:正常删除,头结点另外讨论  方法二:虚拟头结点法  方法三:递归 2.反转链表  方法一:双指针迭代   方法二:递归法 3.链表的中间结点   方法:快慢指针法 4. 链表中倒数第k个结点  方法:快慢指针方法 5.合并两个

    2024年02月11日
    浏览(24)
  • 【数据结构练习】链表面试题锦集一

    目录 前言: 1. 删除链表中所有值为key的节点  方法一:正常删除,头结点另外讨论  方法二:虚拟头结点法  方法三:递归 2.反转链表  方法一:双指针迭代   方法二:递归法 3.链表的中间结点   方法:快慢指针法 4. 链表中倒数第k个结点  方法:快慢指针方法 5.合并两个

    2024年02月11日
    浏览(28)
  • Java并发常见面试题

    何为进程? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行程序,是一个进程从创建、运行到消亡的过程。 在Java中,当我们启动main函数时其实就是启动了一个JVM的进程,而main函数所在的线程就是这个进程中的一个线程,也称主线程

    2024年02月05日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包