1、反转链表
/**
* 这个示例代码中,我们定义了一个 ListNode 类来表示链表的节点,
* 其中包含一个整数值 val 和一个指向下一个节点的指针 next 。
* 然后,我们定义了一个 ReverseLinkedList 类来实现链表反转的功能。
* 在 reverse 方法中,我们使用三个指针 prev 、 current 和 next 来遍历链表并反转指针的指向。
* 最后,我们使用 main 方法来测试代码,创建一个包含5个节点的链表,并输出反转后的链表结果。
*/
public class ReverseLinkedList {
public ListNode reverse(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode prev = null;
ListNode current = head;
ListNode next = null;
while (current != null) {
next = current.next;
current.next = prev;
prev = current;
current = next;
}
return prev;
}
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
head.next.next.next = new ListNode(4);
head.next.next.next.next = new ListNode(5);
ReverseLinkedList solution = new ReverseLinkedList();
ListNode reversedHead = solution.reverse(head);
// 输出反转后的链表
while (reversedHead != null) {
System.out.print(reversedHead.val + " ");
reversedHead = reversedHead.next;
}
}
}
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
2、判断字符串对称
在Java中,判断一个字符串是否对称是一个常见的问题。一个字符串对称指的是它的前半部分和后半部分镜像对称,也就是从中间位置开始,左右对称的字符串。例如,"abcba"和"abccba"都是对称的字符串。
方法一:使用StringBuilder反转字符串
一个简单的方法是使用Java的StringBuilder类来反转字符串,然后判断反转后的字符串是否与原始字符串相等。如果相等,则表示字符串是对称的。
下面是使用StringBuilder反转字符串的代码示例:
public class StringPalindrome {
public static boolean isPalindrome(String str) {
StringBuilder reversed = new StringBuilder(str).reverse();
return str.equals(reversed.toString());
}
public static void main(String[] args) {
String str1 = "abcba";
// 输出 true
System.out.println(isPalindrome(str1));
String str2 = "abccba";
// 输出 true
System.out.println(isPalindrome(str2));
String str3 = "abcd";
// 输出 false
System.out.println(isPalindrome(str3));
}
}
上述代码中的isPalindrome方法接受一个字符串作为参数,并使用StringBuilder类的reverse方法对字符串进行反转。然后,将反转后的字符串与原始字符串进行比较,如果相等,则返回true,否则返回false。
运行上述代码,将会输出以下结果:
true
true
false
方法二:使用双指针
另一种常用的方法是使用双指针来判断字符串是否对称。双指针分别指向字符串的首尾,然后依次比较两个指针所指向的字符是否相等。如果相等,则将指针向中间移动;如果不相等,则表示字符串不对称。
下面是使用双指针判断字符串对称性的代码示例:
public class StringPalindrome {
public static boolean isPalindrome(String str) {
int left = 0;
int right = str.length() - 1;
while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
String str1 = "abcba";
System.out.println(isPalindrome(str1)); // 输出 true
String str2 = "abccba";
System.out.println(isPalindrome(str2)); // 输出 true
String str3 = "abcd";
System.out.println(isPalindrome(str3)); // 输出 false
}
}
上述代码中的isPalindrome方法使用两个指针left和right来比较字符串的首尾字符。如果两个字符不相等,则返回false;否则,将指针向中间移动一位,继续比较下一个字符。当left大于等于right时,表示已经比较完毕,字符串是对称的。
运行上述代码,将会输出以下结果:
true
true
false
3、树的最短路径
import java.util.ArrayList;
import java.util.List;
public class ShortestPath {
private static class Node {
int data;
List<Node> neighbors;
public Node(int data) {
this.data = data;
this.neighbors = new ArrayList<>();
}
}
public static void main(String[] args) {
// 创建一个树
Node root = new Node(0);
root.neighbors.add(new Node(1));
root.neighbors.add(new Node(2));
root.neighbors.add(new Node(3));
// 计算树的最短路径
List<Node> shortestPath = findShortestPath(root, 3);
// 打印最短路径
for (Node node : shortestPath) {
System.out.println(node.data);
}
}
private static List<Node> findShortestPath(Node root, int target) {
// 创建一个队列来存储待访问的节点
Queue<Node> queue = new LinkedList<>();
// 将根节点加入到队列中
queue.add(root);
// 创建一个哈希表来存储每个节点的距离
Map<Node, Integer> distanceMap = new HashMap<>();
distanceMap.put(root, 0);
while (!queue.isEmpty()) {
// 从队列中弹出一个节点
Node node = queue.poll();
// 遍历节点的所有邻居
for (Node neighbor : node.neighbors) {
// 如果邻居节点没有被访问过,则将其加入到队列中
if (!distanceMap.containsKey(neighbor)) {
queue.add(neighbor);
}
// 更新邻居节点的距离
distanceMap.put(neighbor, distanceMap.get(node) + 1);
}
}
// 返回最短路径
return getShortestPath(root, target, distanceMap);
}
private static List<Node> getShortestPath(Node root, int target, Map<Node, Integer> distanceMap) {
// 创建一个列表来存储最短路径
List<Node> shortestPath = new ArrayList<>();
// 从目标节点开始,依次找到最短路径上的所有节点
Node currentNode = target;
while (currentNode != null) {
shortestPath.add(currentNode);
currentNode = distanceMap.get(currentNode) == 0 ? null : distanceMap.get(currentNode) - 1;
}
// 反转列表,得到最短路径
Collections.reverse(shortestPath);
return shortestPath;
}
}
4、二分查找
import java.util.Arrays;
public class BinarySearch {
public static void main(String[] args) {
// 创建一个数组
int[] array = {1, 3, 5, 7, 9};
// 查找元素 5
int index = binarySearch(array, 5);
// 打印元素的索引
System.out.println(index);
}
private static int binarySearch(int[] array, int target) {
// 定义左边界和右边界
int left = 0;
int right = array.length - 1;
// 循环查找
while (left <= right) {
// 计算中间位置
int mid = (left + right) / 2;
// 如果中间位置的元素等于目标元素,则返回中间位置的索引
if (array[mid] == target) {
return mid;
}
// 如果中间位置的元素大于目标元素,则将右边界更新为中间位置 - 1
else if (array[mid] > target) {
right = mid - 1;
}
// 如果中间位置的元素小于目标元素,则将左边界更新为中间位置 + 1
else {
left = mid + 1;
}
}
// 如果没有找到目标元素,则返回 -1
return -1;
}
}
运行结果
2
5、快速排序
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
// 创建一个数组
int[] array = {1, 3, 5, 7, 9, 2, 4, 6, 8};
// 快速排序
quickSort(array, 0, array.length - 1);
// 打印排序后的数组
System.out.println(Arrays.toString(array));
}
private static void quickSort(int[] array, int left, int right) {
// 如果左边界大于右边界,则退出递归
if (left >= right) {
return;
}
// 选择基准元素
int pivot = array[left];
// 将小于基准元素的元素放到左边,将大于基准元素的元素放到右边
int i = left;
int j = right;
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
// 递归对左边和右边的子数组进行排序
quickSort(array, left, j);
quickSort(array, i, right);
}
}
运行结果
[1, 2, 3, 4, 5, 6, 7, 8, 9]
6、冒泡排序
java
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
// 创建一个数组
int[] array = {5, 3, 8, 2, 1};
// 冒泡排序
bubbleSort(array);
// 打印排序后的数组
System.out.println(Arrays.toString(array));
}
private static void bubbleSort(int[] array) {
int n = array.length;
// 外层循环控制排序的轮数
for (int i = 0; i < n - 1; i++) {
// 内层循环控制每一轮的比较和交换
for (int j = 0; j < n - i - 1; j++) {
// 如果相邻的两个元素顺序错误,则交换它们
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
运行结果
[1, 2, 3, 5, 8]
7、判断链表中是否有环
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;
}
public static void main(String[] args) {
// 构建一个有环的链表
ListNode head = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
head.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = node2; // 使链表成环
LinkedListCycle solution = new LinkedListCycle();
boolean hasCycle = solution.hasCycle(head);
System.out.println(hasCycle); // 输出结果为true,表示链表有环
}
}
/**
* 链表的节点类
*/
public class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
8、二叉树
public class BinaryTree {
private Node root;
public BinaryTree() {
this.root = null;
}
public void add(int data) {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
} else {
add(newNode, this.root);
}
}
private void add(Node newNode, Node currentNode) {
if (newNode.data < currentNode.data) {
if (currentNode.left == null) {
currentNode.left = newNode;
} else {
add(newNode, currentNode.left);
}
} else {
if (currentNode.right == null) {
currentNode.right = newNode;
} else {
add(newNode, currentNode.right);
}
}
}
public void inorder() {
inorder(this.root);
}
private void inorder(Node node) {
if (node != null) {
inorder(node.left);
System.out.println(node.data);
inorder(node.right);
}
}
public void preorder() {
preorder(this.root);
}
private void preorder(Node node) {
if (node != null) {
System.out.println(node.data);
preorder(node.left);
preorder(node.right);
}
}
public void postorder() {
postorder(this.root);
}
private void postorder(Node node) {
if (node != null) {
postorder(node.left);
postorder(node.right);
System.out.println(node.data);
}
}
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
tree.add(10);
tree.add(5);
tree.add(15);
tree.add(2);
tree.add(7);
tree.add(12);
tree.add(17);
System.out.println("Inorder traversal:");
tree.inorder();
System.out.println("Preorder traversal:");
tree.preorder();
System.out.println("Postorder traversal:");
tree.postorder();
}
}
9、LRU算法
import java.util.HashMap;
import java.util.Map;
public class LRUCache {
private final int capacity;
private final Map<Integer, Node> map;
private final Node head;
private final Node tail;
public LRUCache(int capacity) {
this.capacity = capacity;
this.map = new HashMap<>(capacity);
this.head = new Node();
this.tail = new Node();
head.next = tail;
tail.prev = head;
}
public int get(int key) {
Node node = map.get(key);
if (node == null) {
return -1;
}
// 将节点移到链表头部
removeNode(node);
addToHead(node);
return node.value;
}
public void put(int key, int value) {
Node node = map.get(key);
if (node == null) {
// 缓存中没有该节点,创建一个新的节点
node = new Node(key, value);
map.put(key, node);
// 添加到链表头部
addToHead(node);
} else {
// 缓存中有该节点,更新节点的值
node.value = value;
// 将节点移到链表头部
removeNode(node);
addToHead(node);
}
// 如果缓存的大小超过了容量,则删除链表尾部的节点
if (map.size() > capacity) {
Node tail = removeTail();
map.remove(tail.key);
}
}
private void removeNode(Node node) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
private void addToHead(Node node) {
node.next = head.next;
head.next.prev = node;
head.next = node;
node.prev = head;
}
private Node removeTail() {
Node node = new Node();
Node tail = node.prev;
removeNode(tail);
return tail;
}
private static class Node {
private int key;
private int value;
private Node prev;
private Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
}
public Node() {
}
}
}
10、数组合并
方法一:
int[] arr1 = {1, 2, 3};
int[] arr2 = {4, 5, 6};
int[] result = new int[arr1.length + arr2.length];
System.arraycopy(arr1, 0, result, 0, arr1.length);
System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}
方法一:
int[] arr1 = {1, 2, 3};
int[] arr2 = {4, 5, 6};
int[] result = Arrays.copyOf(arr1, arr1.length + arr2.length);
System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
for (int i = 0; i < result.length; i++) {
System.out.println(result[i]);
}