• 5大数据结构


    1. 栈结构

    例题1:字符串括号匹配

    import java.util.Stack;
    
    public class BracketMatching {
        public static boolean isBracketMatching(String s) {
            Stack<Character> stack = new Stack<>();
            
            for (char c : s.toCharArray()) {
                if (c == '(' || c == '{' || c == '[') {
                    stack.push(c);
                } else {
                    if (stack.isEmpty()) {
                        return false;
                    }
                    
                    char top = stack.pop();
                    if ((c == ')' && top != '(') || (c == '}' && top != '{') || (c == ']' && top != '[')) {
                        return false;
                    }
                }
            }
            
            return stack.isEmpty();
        }
    
        public static void main(String[] args) {
            String s1 = "{[()]}"; // valid
            String s2 = "{[(])}"; // invalid
            String s3 = "()[]{}"; // valid
            
            System.out.println(isBracketMatching(s1)); // output: true
            System.out.println(isBracketMatching(s2)); // output: false
            System.out.println(isBracketMatching(s3)); // output: true
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    例题2:最小栈

    import java.util.Stack;
    
    public class MinStack {
        private Stack<Integer> stack;
        private Stack<Integer> minStack;
    
        public MinStack() {
            stack = new Stack<>();
            minStack = new Stack<>();
        }
    
        public void push(int x) {
            stack.push(x);
            if (minStack.isEmpty() || x <= minStack.peek()) {
                minStack.push(x);
            }
        }
    
        public void pop() {
            if (stack.pop().equals(minStack.peek())) {
                minStack.pop();
            }
        }
    
        public int top() {
            return stack.peek();
        }
    
        public int getMin() {
            return minStack.peek();
        }
    
        public static void main(String[] args) {
            MinStack minStack = new MinStack();
            minStack.push(3);
            minStack.push(5);
            minStack.push(2);
            
            System.out.println(minStack.getMin()); // output: 2
            minStack.pop();
            System.out.println(minStack.top()); // output: 5
            System.out.println(minStack.getMin()); // output: 3
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    例题3:逆波兰表达式求值

    import java.util.Stack;
    
    public class EvaluateReversePolishNotation {
        public static int evalRPN(String[] tokens) {
            Stack<Integer> stack = new Stack<>();
            
            for (String token : tokens) {
                if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")) {
                    int b = stack.pop();
                    int a = stack.pop();
                    
                    switch (token) {
                        case "+":
                            stack.push(a + b);
                            break;
                        case "-":
                            stack.push(a - b);
                            break;
                        case "*":
                            stack.push(a * b);
                            break;
                        case "/":
                            stack.push(a / b);
                            break;
                    }
                } else {
                    stack.push(Integer.parseInt(token));
                }
            }
            
            return stack.pop();
        }
    
        public static void main(String[] args) {
            String[] tokens1 = {"2", "1", "+", "3", "*"}; // (2 + 1) * 3 = 9
            String[] tokens2 = {"4", "13", "5", "/", "+"}; // 4 + (13 / 5) = 6
            
            System.out.println(evalRPN(tokens1)); // output: 9
            System.out.println(evalRPN(tokens2)); // output: 6
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    例题4:下一个更大元素

    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Stack;
    
    public class NextGreaterElement {
        public static int[] nextGreaterElement(int[] nums) {
            int[] result = new int[nums.length];
            Arrays.fill(result, -1);
            Stack<Integer> stack = new Stack<>();
            Map<Integer, Integer> map = new HashMap<>();
    
            for (int i = 0; i < nums.length; i++) {
                while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) {
                    int index = stack.pop();
                    result[index] = nums[i];
                }
                stack.push(i);
            }
    
            for (int i = 0; i < nums.length; i++) {
                while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) {
                    int index = stack.pop();
                    result[index] = nums[i];
                }
            }
    
            return result;
        }
    
        public static void main(String[] args) {
            int[] nums1 = {4, 2, 5, 7}; // output: [5, 5, 7, -1]
            int[] nums2 = {3, 1, 2, 4}; // output: [4, 2, 4, -1]
    
            int[] result1 = nextGreaterElement(nums1);
            int[] result2 = nextGreaterElement(nums2);
    
            System.out.println(Arrays.toString(result1));
            System.out.println(Arrays.toString(result2));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    2. 队列结构

    题目1: 实现一个队列,包括入队和出队操作,并判断队列是否为空。

    public class Queue {
        private int[] data; // 存储队列元素的数组
        private int front; // 队首指针
        private int rear; // 队尾指针
    
        public Queue(int size) {
            data = new int[size];
            front = 0;
            rear = -1;
        }
    
        public boolean isEmpty() {
            return rear == -1;
        }
    
        public void enqueue(int value) {
            data[++rear] = value;
        }
    
        public int dequeue() {
            int value = data[front++];
            if (front > rear) {
                front = 0;
                rear = -1;
            }
            return value;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    题目2: 判断给定的字符串是否是回文字符串。

    import java.util.LinkedList;
    
    public class Palindrome {
        public static boolean isPalindrome(String str) {
            LinkedList<Character> queue = new LinkedList<>();
            
            // 将字符串的每个字符入队
            for (int i = 0; i < str.length(); i++) {
                queue.addLast(str.charAt(i));
            }
            
            // 依次出队和字符串的每个字符比较
            for (int i = 0; i < str.length(); i++) {
                if (queue.removeFirst() != str.charAt(i)) {
                    return false;
                }
            }
            
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    题目3: 使用队列实现栈。

    import java.util.LinkedList;
    
    public class Stack {
        private LinkedList<Integer> queue;
    
        public Stack() {
            queue = new LinkedList<>();
        }
    
        public void push(int value) {
            queue.addLast(value);
        }
    
        public int pop() {
            if (queue.isEmpty()) {
                throw new IllegalStateException("Stack is empty.");
            }
    
            // 将队列中除最后一个元素外的所有元素出队并入队,实现栈的后进先出特性
            int size = queue.size();
            for (int i = 0; i < size - 1; i++) {
                int value = queue.removeFirst();
                queue.addLast(value);
            }
    
            return queue.removeFirst();
        }
    
        public int top() {
            if (queue.isEmpty()) {
                throw new IllegalStateException("Stack is empty.");
            }
    
            return queue.getLast();
        }
    
        public boolean isEmpty() {
            return queue.isEmpty();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    题目4: 使用队列实现猫狗队列,可以按顺序存储猫和狗,并可以按顺序弹出猫和狗。

    import java.util.LinkedList;
    
    public class AnimalQueue {
        private LinkedList<Animal> catQueue;
        private LinkedList<Animal> dogQueue;
        private int order;
    
        public AnimalQueue() {
            catQueue = new LinkedList<>();
            dogQueue = new LinkedList<>();
            order = 0;
        }
    
        public void enqueue(Animal animal) {
            animal.setOrder(order++);
    
            if (animal instanceof Cat) {
                catQueue.addLast(animal);
            } else if (animal instanceof Dog) {
                dogQueue.addLast(animal);
            }
        }
    
        public Animal dequeueAny() {
            if (catQueue.isEmpty() && dogQueue.isEmpty()) {
                throw new IllegalStateException("No animals in the queue.");
            } else if (catQueue.isEmpty()) {
                return dogQueue.removeFirst();
            } else if (dogQueue.isEmpty()) {
                return catQueue.removeFirst();
            } else {
                if (catQueue.getFirst().getOrder() < dogQueue.getFirst().getOrder()) {
                    return catQueue.removeFirst();
                } else {
                    return dogQueue.removeFirst();
                }
            }
        }
    
        public Cat dequeueCat() {
            if (catQueue.isEmpty()) {
                throw new IllegalStateException("No cats in the queue.");
            }
            return (Cat) catQueue.removeFirst();
        }
    
        public Dog dequeueDog() {
            if (dogQueue.isEmpty()) {
                throw new IllegalStateException("No dogs in the queue.");
            }
            return (Dog) dogQueue.removeFirst();
        }
    }
    
    class Animal {
        private String name;
        private int order;
    
        public Animal(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public int getOrder() {
            return order;
        }
    
        public void setOrder(int order) {
            this.order = order;
        }
    }
    
    class Cat extends Animal {
        public Cat(String name) {
            super(name);
        }
    }
    
    class Dog extends Animal {
        public Dog(String name) {
            super(name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    2. 堆结构

    例题一:使用堆结构实现一个最小堆

    import java.util.ArrayList;
    import java.util.List;
    
    public class MinHeap {
        private List<Integer> heap;
    
        public MinHeap() {
            heap = new ArrayList<>();
        }
    
        // 获取父节点索引
        private int getParentIndex(int childIndex) {
            return (childIndex - 1) / 2;
        }
    
        // 获取左孩子节点索引
        private int getLeftChildIndex(int parentIndex) {
            return 2 * parentIndex + 1;
        }
    
        // 获取右孩子节点索引
        private int getRightChildIndex(int parentIndex) {
            return 2 * parentIndex + 2;
        }
    
        // 上浮操作,将新插入的元素与父节点比较,如果小于父节点就交换位置,直到满足最小堆的性质
        private void siftUp(int index) {
            while (index > 0) {
                int parentIndex = getParentIndex(index);
                if (heap.get(index) < heap.get(parentIndex)) {
                    swap(index, parentIndex);
                    index = parentIndex;
                } else {
                    break;
                }
            }
        }
    
        // 下沉操作,将顶部元素与左右孩子节点中较小的比较,如果大于孩子节点就交换位置,直到满足最小堆的性质
        private void siftDown(int index) {
            int leftChildIndex = getLeftChildIndex(index);
            int rightChildIndex = getRightChildIndex(index);
            int smallestIndex = index;
    
            if (leftChildIndex < heap.size() && heap.get(leftChildIndex) < heap.get(smallestIndex)) {
                smallestIndex = leftChildIndex;
            }
            if (rightChildIndex < heap.size() && heap.get(rightChildIndex) < heap.get(smallestIndex)) {
                smallestIndex = rightChildIndex;
            }
    
            if (smallestIndex != index) {
                swap(index, smallestIndex);
                siftDown(smallestIndex);
            }
        }
    
        // 交换两个元素的位置
        private void swap(int index1, int index2) {
            int temp = heap.get(index1);
            heap.set(index1, heap.get(index2));
            heap.set(index2, temp);
        }
    
        // 插入元素
        public void insert(int value) {
            heap.add(value);
            siftUp(heap.size() - 1);
        }
    
        // 删除并返回堆顶元素
        public int deleteMin() {
            if (heap.isEmpty()) {
                throw new IllegalStateException("Heap is empty");
            }
            int minValue = heap.get(0);
            heap.set(0, heap.get(heap.size() - 1));
            heap.remove(heap.size() - 1);
            siftDown(0);
            return minValue;
        }
    
        // 获取堆的大小
        public int size() {
            return heap.size();
        }
    
        // 判断堆是否为空
        public boolean isEmpty() {
            return heap.isEmpty();
        }
    
        // 打印堆中的元素
        public void printHeap() {
            for (int i = 0; i < heap.size(); i++) {
                System.out.print(heap.get(i) + " ");
            }
            System.out.println();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    例题二:使用堆结构实现一个优先级队列

    import java.util.PriorityQueue;
    
    public class PriorityQueueExample {
        public static void main(String[] args) {
            // 创建一个优先级队列
            PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
    
            // 添加元素到优先级队列
            priorityQueue.offer(5);
            priorityQueue.offer(3);
            priorityQueue.offer(8);
            priorityQueue.offer(1);
            priorityQueue.offer(2);
    
            // 打印优先级队列中的元素
            System.out.println("Priority Queue: " + priorityQueue);
    
            // 获取并移除优先级队列中的最小元素
            int minElement = priorityQueue.poll();
            System.out.println("Minimum Element: " + minElement);
    
            // 打印优先级队列中的元素
            System.out.println("Priority Queue: " + priorityQueue);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    这是一个使用Java内置的PriorityQueue类实现的优先级队列示例。使用PriorityQueue的offer()方法可以添加元素到队列中,poll()方法可以获取并移除队列中的最小元素。

    4. 链表结构

    1. 反转链表

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }
    
    public class ReverseLinkedList {
        public ListNode reverseList(ListNode head) {
            ListNode prev = null; // 前驱节点
            ListNode curr = head; // 当前节点
            while (curr != null) {
                ListNode nextTemp = curr.next; // 保存当前节点的下一个节点
                curr.next = prev; // 当前节点的指针指向前驱节点
                prev = curr; // 前驱节点向后移动
                curr = nextTemp; // 当前节点向后移动
            }
            return prev; // 返回反转后的头节点
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2. 删除链表的倒数第N个节点

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }
    
    public class RemoveNthNodeFromEnd {
        public ListNode removeNthFromEnd(ListNode head, int n) {
            ListNode dummy = new ListNode(0); // 创建虚拟头节点
            dummy.next = head;
            ListNode first = dummy; // 快指针
            ListNode second = dummy; // 慢指针
            for (int i = 0; i <= n; i++) {
                first = first.next; // 快指针先向后移动n步
            }
            while (first != null) {
                first = first.next; // 快指针继续向后移动
                second = second.next; // 慢指针向后移动
            }
            second.next = second.next.next; // 删除倒数第N个节点
            return dummy.next; // 返回头节点
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3. 合并两个有序链表

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }
    
    public class MergeTwoSortedLists {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            ListNode dummy = new ListNode(0); // 创建虚拟头节点
            ListNode curr = dummy; // 当前节点
            while (l1 != null && l2 != null) {
                if (l1.val < l2.val) {
                    curr.next = l1; // 将l1节点接到当前节点后面
                    l1 = l1.next; // l1节点向后移动
                } else {
                    curr.next = l2; // 将l2节点接到当前节点后面
                    l2 = l2.next; // l2节点向后移动
                }
                curr = curr.next; // 当前节点向后移动
            }
            if (l1 != null) {
                curr.next = l1; // 将剩余的l1节点接到当前节点后面
            }
            if (l2 != null) {
                curr.next = l2; // 将剩余的l2节点接到当前节点后面
            }
            return dummy.next; // 返回合并后的头节点
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    4. 判断链表是否有环

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }
    
    public class LinkedListCycle {
        public boolean hasCycle(ListNode head) {
            if (head == null || head.next == null) {
                return false; // 链表为空或只有一个节点,不可能有环
            }
            ListNode slow = head; // 慢指针
            ListNode fast = head.next; // 快指针
            while (slow != fast) {
                if (fast == null || fast.next == null) {
                    return false; // 快指针走到链表尾部,不存在环
                }
                slow = slow.next; // 慢指针向后移动一步
                fast = fast.next.next; // 快指针向后移动两步
            }
            return true; // 快慢指针相遇,存在环
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    5. 返回链表的中间节点

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }
    
    public class MiddleOfLinkedList {
        public ListNode middleNode(ListNode head) {
            ListNode slow = head; // 慢指针
            ListNode fast = head; // 快指针
            while (fast != null && fast.next != null) {
                slow = slow.next; // 慢指针移动一步
                fast = fast.next.next; // 快指针移动两步
            }
            return slow; // 返回中间节点
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6. 删除链表中的重复元素

    class ListNode {
        int val;
        ListNode next;
        ListNode(int x) {
            val = x;
        }
    }
    
    public class RemoveDuplicatesFromSortedList {
        public ListNode deleteDuplicates(ListNode head) {
            ListNode curr = head;
            while (curr != null && curr.next != null) {
                if (curr.val == curr.next.val) {
                    curr.next = curr.next.next; // 删除重复节点
                } else {
                    curr = curr.next; // 不重复,节点向后移动
                }
            }
            return head; // 返回头节点
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5. hash思想

    题目一:找出数组中重复的数字

    问题描述:给定一个整数数组,数组中有些数字是重复的,找出数组中任意一个重复的数字。

    解决思路:使用哈希思想,可以借助集合(Set)来模拟哈希表,遍历数组,将数字放入集合中,如果集合中已经存在该数字,则找到了重复的数字。

    import java.util.HashSet;
    
    public class DuplicateNumbers {
        public static int findDuplicate(int[] nums) {
            // 创建一个集合用于存储已经遍历过的数字
            HashSet<Integer> set = new HashSet<>();
            
            // 遍历数组,将数字放入集合中
            for (int num : nums) {
                // 如果集合中已经存在该数字,返回该数字
                if (set.contains(num)) {
                    return num;
                }
                
                // 将数字放入集合中
                set.add(num);
            }
            
            // 如果没有找到重复的数字,则返回-1
            return -1;
        }
    
        public static void main(String[] args) {
            int[] nums = {2, 3, 1, 0, 2, 5, 3};
            int duplicate = findDuplicate(nums);
            System.out.println("Duplicate Number: " + duplicate);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    题目二:找出数组中只出现一次的数字

    问题描述:给定一个整数数组,数组中有两个数字只出现了一次,其他数字都出现了两次,请找出这两个只出现一次的数字。

    解决思路:使用哈希思想,可以借助集合(Set)来模拟哈希表,遍历数组,将数字放入集合中,如果集合中已经存在该数字,则从集合中移除该数字,最后集合中剩余的两个数字就是只出现一次的数字。

    import java.util.HashSet;
    
    public class SingleNumbers {
        public static int[] findSingleNumbers(int[] nums) {
            // 创建一个集合用于存储只出现一次的数字
            HashSet<Integer> set = new HashSet<>();
            
            // 遍历数组,将数字放入集合中或从集合中移除
            for (int num : nums) {
                // 如果集合中已经存在该数字,将其从集合中移除
                if (set.contains(num)) {
                    set.remove(num);
                } else {
                    // 否则将数字放入集合中
                    set.add(num);
                }
            }
            
            // 将集合中的数字转化为数组并返回
            int[] result = new int[2];
            int index = 0;
            for (int num : set) {
                result[index] = num;
                index++;
            }
            return result;
        }
    
        public static void main(String[] args) {
            int[] nums = {2, 3, 1, 0, 2, 5, 3};
            int[] singleNumbers = findSingleNumbers(nums);
            System.out.println("Single Numbers: " + singleNumbers[0] + ", " + singleNumbers[1]);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    题目三:找出字符串中第一个不重复的字符

    问题描述:给定一个字符串,找出字符串中第一个不重复的字符,并返回其索引。

    解决思路:使用哈希思想,可以借助数组来模拟哈希表,遍历字符串,统计每个字符出现的次数,然后再次遍历字符串,找到第一个出现次数为1的字符,返回其索引。

    public class FirstUniqueCharacter {
        public static int firstUniqChar(String s) {
            // 创建一个长度为26的数组,用于统计每个字符出现的次数
            int[] count = new int[26];
            
            // 第一次遍历字符串,统计每个字符出现的次数
            for (char c : s.toCharArray()) {
                count[c - 'a']++;
            }
            
            // 第二次遍历字符串,找到第一个出现次数为1的字符,返回其索引
            for (int i = 0; i < s.length(); i++) {
                if (count[s.charAt(i) - 'a'] == 1) {
                    return i;
                }
            }
            
            // 如果字符串中没有不重复的字符,则返回-1
            return -1;
        }
    
        public static void main(String[] args) {
            String s = "leetcode";
            int index = firstUniqChar(s);
            System.out.println("First Unique Character Index: " + index);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    C语言——矩阵转置
    QGIS下载NASA SRTM数据(插件)
    OpenGL ES freeglut 下载和使用
    IBM LSF 任务调度系统的主要术语和概念
    5.k8s jenkins集成k8s一键发布案例
    基于java多特蒙德周边商城系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
    Apple Watch无法开机怎么办?苹果手表不能开机解决方法!
    AIGC革新,将文字或者LOGO融入AI视频基于PIKA-labs(Python3.10)
    多线程与高并发编程二
    RSA加解密(非对称加密)
  • 原文地址:https://blog.csdn.net/m0_59076472/article/details/134484314