下面是一些常见的数据结构面试题以及使用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
这种题目可以通过快速选择来解决,这是基于快速排序的一种优化算法。文章来源地址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模板网!