Compare commits

...

77 Commits

Author SHA1 Message Date
bd860423c4 Update SinglyLinkedListTest.java 2024-07-11 17:23:00 +08:00
dfda3d7f08 Update SinglyLinkedList.java 2024-07-11 17:22:58 +08:00
042fbd164a Create SinglyLinkedListTest.java 2024-07-11 16:44:09 +08:00
c6b68cd40e Create SinglyLinkedList.java 2024-07-11 16:44:06 +08:00
fd72f740eb Update DynamicArrayTest.java 2024-07-11 15:35:20 +08:00
9a98ed3770 Update DynamicArray.java 2024-07-11 15:35:17 +08:00
9eba905fc0 Update pom.xml 2024-07-11 15:35:13 +08:00
0295bde18c Create DynamicArrayTest.java 2024-07-11 10:41:46 +08:00
4b6f4dc631 Update BinarySearchTest.java 2024-07-11 10:41:43 +08:00
6ca0b464a8 Create DynamicArray.java 2024-07-11 10:41:38 +08:00
a3f5a177a5 Update BinarySearch.java 2024-07-11 10:41:28 +08:00
feb1f5fcad Update BinarySearch.java 2024-07-10 17:11:18 +08:00
b5059f6996 Update BinarySearchTest.java 2024-07-10 16:58:39 +08:00
022850f76c Update BinarySearch.java 2024-07-10 16:58:37 +08:00
35e5acb50f Update BinarySearchTest.java 2024-07-10 00:31:05 +08:00
4f478c08ac Update BinarySearch.java 2024-07-10 00:31:03 +08:00
7827051d82 Update BinarySearch.java 2024-07-09 23:58:32 +08:00
664b4478d7 Update BinarySearch.java 2024-07-09 23:46:31 +08:00
922c779457 Update BinarySearch.java 2024-07-09 23:42:12 +08:00
b415741eb0 Update .gitignore 2024-07-09 23:01:25 +08:00
67d4fa3983 Update BinarySearch.java 2024-07-09 23:00:50 +08:00
abd073c2b5 Update pom.xml 2024-07-09 23:00:46 +08:00
c664823f9c Update BinarySearchTest.java 2024-07-09 22:48:47 +08:00
2c2ee20dd2 Update pom.xml 2024-07-09 22:48:44 +08:00
45b40688c7 Create BinarySearchTest.java 2024-07-09 22:46:10 +08:00
438abeca95 Delete test.java 2024-07-09 22:46:07 +08:00
6fb29ad89e Delete Solution.java 2024-07-09 22:46:05 +08:00
1d77960011 Delete ListNode.java 2024-07-09 22:46:03 +08:00
732d006f3b Create test.java 2024-07-09 22:46:00 +08:00
e27cb1fb87 Create Solution.java 2024-07-09 22:45:58 +08:00
d589c45e45 Create ListNode.java 2024-07-09 22:45:55 +08:00
97eb4196e9 Create BinarySearch.java 2024-07-09 22:45:53 +08:00
23dc31f9ae Update README.md 2024-07-09 22:45:50 +08:00
a4fd3e2a15 Create pom.xml 2024-07-09 22:45:40 +08:00
5d29f810a2 Update test.java 2024-07-09 21:53:33 +08:00
2628f99a31 Update Solution.java 2024-07-09 21:53:30 +08:00
27074cb4c6 Update test.java 2024-07-08 21:37:57 +08:00
5a0d46a2d9 Update Solution.java 2024-07-08 21:37:55 +08:00
6c39c4d462 Update test.java 2024-07-08 21:14:38 +08:00
b75d236fbb Update Solution.java 2024-07-08 21:14:35 +08:00
c72996f342 Update Solution.java 2024-07-08 20:21:49 +08:00
01f220bacf Create ListNode.java 2024-07-08 20:21:46 +08:00
95ea49c5a0 更新 Solution.java 2023-09-13 11:49:23 +08:00
cd41388601 更新 test.java 2023-09-13 11:49:21 +08:00
69d78bd534 更新 Solution.java 2023-09-12 16:43:16 +08:00
8bd3a3b7a3 更新 Solution.java 2023-09-12 16:37:22 +08:00
7e82ef55c0 更新 test.java 2023-09-12 16:37:19 +08:00
d38af5164a 更新 Solution.java 2023-09-12 16:24:57 +08:00
64af01a85d 更新 Solution.java 2023-09-12 16:15:54 +08:00
959157e587 更新 test.java 2023-09-12 16:15:51 +08:00
ded5c3051c 更新 Solution.java 2023-09-12 15:17:38 +08:00
2277ac48a3 更新 Solution.java 2023-09-12 15:12:36 +08:00
465b042d7e Update test.java 2023-09-09 14:53:42 +08:00
c43301205e Update Solution.java 2023-09-09 14:53:38 +08:00
57ac140a08 更新 test.java 2023-09-06 17:34:50 +08:00
199077684b 更新 test.java 2023-09-06 16:41:20 +08:00
ac72c9bbaa 更新 test.java 2023-09-06 16:28:23 +08:00
9ea63b7eff 更新 Solution.java 2023-09-06 16:27:08 +08:00
8f15fee32e 更新 test.java 2023-09-06 16:25:38 +08:00
0eb5aa8e9e 更新 Solution.java 2023-09-06 16:25:36 +08:00
1bdd2f6973 更新 .gitignore 2023-09-06 16:25:25 +08:00
239dcec5ae 删除 Solution.iml 2023-09-06 16:24:53 +08:00
85497363cf 删除 vcs.xml 2023-09-06 16:24:50 +08:00
a264682bc4 删除 modules.xml 2023-09-06 16:24:43 +08:00
05b608b6d9 删除 misc.xml 2023-09-06 16:24:36 +08:00
a83429a6b7 更新 Solution.java 2023-09-06 15:06:26 +08:00
654ae87668 更新 test.java 2023-09-06 15:06:23 +08:00
8ce22bbbbb 更新 Solution.java 2023-09-06 14:28:56 +08:00
e57ebeadf8 更新 test.java 2023-09-06 14:28:53 +08:00
755fdc488a 更新 test.java 2023-09-06 12:01:01 +08:00
ec10ce6c8a 更新 Solution.java 2023-09-06 12:00:57 +08:00
e20fbc3713 删除 Solution.iml 2023-09-06 11:41:42 +08:00
8eb127378f 更新 .gitignore 2023-09-06 11:41:30 +08:00
263e8e0654 删除 workspace.xml 2023-09-06 11:38:47 +08:00
5bd8197e78 删除 vcs.xml 2023-09-06 11:38:38 +08:00
22bc22261f 更新 Solution.java 2023-09-05 18:11:31 +08:00
bf2e20cde9 Untrack .idea/workspace.xml 2023-09-05 18:11:23 +08:00
17 changed files with 1035 additions and 238 deletions

2
.gitignore vendored
View File

@@ -1,6 +1,7 @@
<<<<<<< HEAD
### IntelliJ IDEA ###
out/
/target/
!**/src/main/**/out/
!**/src/test/**/out/
@@ -51,6 +52,7 @@ bin/
*.tar.gz
*.rar
.idea/*
Solution.iml
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

91
.idea/workspace.xml generated
View File

@@ -1,91 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="45f625e1-36c7-4942-8f7c-ba3ebe9a7d53" name="变更" comment="">
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Class" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="2Uvat6WoxeDXNA4JCjbald5NvRW" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"WebServerToolWindowFactoryState": "false",
"ignore.virus.scanning.warn.message": "true",
"last_opened_file_path": "C:/Users/wangh/Desktop/code/java/Solution",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"project.structure.last.edited": "模块",
"project.structure.proportion": "0.0",
"project.structure.side.proportion": "0.0",
"settings.editor.selected.configurable": "preferences.lookFeel",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager">
<configuration name="test" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="solution.test" />
<module name="Solution" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="solution.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<recent_temporary>
<list>
<item itemvalue="应用程序.test" />
</list>
</recent_temporary>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="45f625e1-36c7-4942-8f7c-ba3ebe9a7d53" name="变更" comment="" />
<created>1693822719192</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1693822719192</updated>
<workItem from="1693822720224" duration="5742000" />
<workItem from="1693895305007" duration="5358000" />
<workItem from="1693900694533" duration="6345000" />
<workItem from="1693971038966" duration="302000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

View File

@@ -1,2 +1,2 @@
# solution.Solution
# main.practice.Solution

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

37
pom.xml Normal file
View File

@@ -0,0 +1,37 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nbee</groupId>
<artifactId>solution</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@@ -0,0 +1,141 @@
package com.nbee.solution.practice;
import java.util.Arrays;
class BinarySearch {
public static int binarySearchBasic(int[] nums, int target) {
int i = 0, j = nums.length - 1;//设置指针和初始值
while (i <= j) {//此处的条件是i<=j而不是i<j
// int m = ((i + j) / 2);
int m = (i + j) >>> 1; //按位右移补零操作符。相当于除2解决溢出问题
if (target < nums[m]) {//如果中间值大于目标值,则将右指针向左移动
j = m - 1;
} else if (nums[m] < target) {//如果中间值小于目标值,则将左指针向右移动
i = m + 1;
} else {
return m;
}
}
return -1;
/**
* 为什么必须是i<=j?
* 在二分搜索中,使用条件 i <= j 作为循环的继续条件是为了确保在数组只剩下一个元素时,仍然能够检查这个元素。这是因为在二分搜索中
* 你每次都在缩小搜索范围,直到没有元素剩余。如果用 i < j 作为条件,当 i 和 j 相等时,这个位置的元素将不会被检查,可能导致漏掉目标元素。
*/
}
public static int binarySearchAlternative(int[] nums, int target) {
int i = 0, j = nums.length;
while (i < j) {
int m = (i + j) >>> 1;
if (target < nums[m]) {
j = m;
} else if (nums[m] < target) {
i = m + 1;
} else {
return m;
}
}
return -1;
}
public static int binarySearch01(int[] nums, int target) {
int i = 0, j = nums.length;
while (1 < j - i) {
int m = (i + j) >>> 1;
if (target < nums[m]) {
j = m;
} else {
i = m;
}
}
if (nums[i] == target) {
return i;
} else {
return -1;
}
}
public static int binarySearchLeftMost(int[] nums, int target) {
int i = 0, j = nums.length - 1;
int candidate = -1;
while (i <= j) {
int m = (i + j) >>> 1;
if (target < nums[m]) {
j = m - 1;
} else if (nums[m] < target) {
i = m + 1;
} else {
candidate = m;
j = m - 1;
}
}
return candidate;
}
public static int binarySearchRightMost(int[] nums, int target) {
int i = 0, j = nums.length - 1;
int candidate = -1;
while (i <= j) {
int m = (i + j) >>> 1;
if (target < nums[m]) {
j = m - 1;
} else if (nums[m] < target) {
i = m + 1;
} else {
candidate = m;
i = m + 1;
}
}
return candidate;
}
//改进二分查找
public static int binarySearchLeftMost0(int[] nums, int target) {
int i = 0, j = nums.length - 1;
while (i <= j) {
int m = (i + j) >>> 1;
if (target < nums[m]) {
j = m - 1;
} else {
i = m + 1;
}
}
return i;
}
public static int binarySearchRightMost0(int[] nums, int target) {
int i = 0, j = nums.length - 1;
while (i <= j) {
int m = (i + j) >>> 1;
if (target < nums[m]) {
j = m - 1;
} else {
i = m + 1;
}
}
return i - 1;
}
/**
* 给你一个按照非递减顺序排列的整数数组 nums和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
* 如果数组中不存在目标值 target返回 [-1, -1]。
* 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
*
* @param nums
* @param target
* @return
*/
public static int[] searchRange(int[] nums, int target) {
if (nums.length == 0){
return new int[]{-1,-1};
}
if (nums.length == 1){
return new int[]{0,0};
}
int left = binarySearchLeftMost(nums, target);
int right = binarySearchRightMost(nums,target);
return new int[]{left,right};
}
}

View File

@@ -0,0 +1,91 @@
package com.nbee.solution.practice;
import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;
public class DynamicArray implements Iterable<Integer> {
private int size = 0;
private int capacity = 8;
private int[] array = {};
public void addList(int element) {
add(size, element);
}
public void add(int index, int element) {
checkAndGrow();
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
if (index >= 0 && index < size) {
System.arraycopy(array, index, array, index + 1, size - index);
}
array[index] = element;
size++;
}
private void checkAndGrow() {
if (size == 0) {
array = new int[capacity];
} else if (size == capacity) {
capacity = capacity + (capacity >>> 1);
int[] newArray = new int[capacity];
System.arraycopy(array, 0, newArray, 0, size);
array = newArray;
}
}
public int getSize() {
return size;
}
public int get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
return array[index];
}
public void forEach0(Consumer<Integer> consumer) {
for (int i = 0; i < size; i++) {
consumer.accept(array[i]);
}
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
int i = 0;
@Override
public boolean hasNext() {
return i < size;
}
@Override
public Integer next() {
return array[i++];
}
};
}
public IntStream stream() {
return IntStream.of(Arrays.copyOfRange(array, 0, size));
}
public int remove(int index) {
int removed = array[index];
if (index < size - 1) {
System.arraycopy(array, index + 1, array, index, size - index - 1);
size--;
}
return removed;
}
public String toString() {
return Arrays.toString(Arrays.copyOfRange(array, 0, size));
}
}

View File

@@ -0,0 +1,81 @@
package com.nbee.solution.practice;
import java.util.Iterator;
import java.util.function.Consumer;
/**
* 链表类
*/
public class SinglyLinkedList implements Iterable<Integer> {
private Node head;
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
Node p = head;
@Override
public boolean hasNext() {
return p != null;
}
@Override
public Integer next() {
int value = p.value;
p = p.next;
return value;
}
};
}
private Node findLast() {
if (head == null) {
return null;
}
Node p;
for (p = head; p != null; p = p.next) {
}
return p;
}
public void addLast(int value) {
Node last = findLast();
if (last == null){
addFirst(value);
return;
}
last.next = new Node(value, null);
}
private static class Node {
int value;
Node next;
Node(int value, Node next) {
this.value = value;
this.next = next;
}
}
public void addFirst(int value) {
//链表为空
// head = new Node(value,null);
//链表非空,包含了链表为空的情况
head = new Node(value, head);
}
public void loop(Consumer<Integer> consumer) {
Node p = head;
while (p != null) {
consumer.accept(p.value);
p = p.next;
}
}
public void loop0(Consumer<Integer> consumer) {
for (Node p = head; p != null; p = p.next) {
consumer.accept(p.value);
}
}
}

View File

@@ -0,0 +1,20 @@
package com.nbee.solution.solution;
public class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}

View File

@@ -0,0 +1,405 @@
package com.nbee.solution.solution;
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
//给定一个字符串 s ,找出其中不含有重复字符的 最长子串 的长度。
public static int lengthOfLongestSubstring(String s) {
// 哈希集合,记录每个字符是否出现过
Set<Character> occ = new HashSet<Character>();
int n = s.length();
// 右指针,初始值为 -1相当于我们在字符串的左边界的左侧还没有开始移动
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.remove(s.charAt(i - 1));
}
while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
// 不断地移动右指针
occ.add(s.charAt(rk + 1));
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
}
//计算最大价格
public static int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int minPrice = prices[0];
int maxProfit = 0;
for (int price : prices) {
// 更新最小价格
minPrice = Math.min(minPrice, price);
// 计算当前价格的潜在利润并更新最大利润
int potentialProfit = price - minPrice;
maxProfit = Math.max(maxProfit, potentialProfit);
}
return maxProfit;
}
//哈希映射算法(Hash Mapping Algorithm)用于找出一个数组中的众数(majority element)
public static int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
// maxNum 表示元素maxCount 表示元素出现的次数
int maxNum = 0, maxCount = 0;
for (int num: nums) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
if (count > maxCount) {
maxCount = count;
maxNum = num;
}
}
return maxNum;
}
//摩尔投票算法(Boyer-Moore Voting Algorithm)来找出数组中的众数
public static int majorityElement1(int[] nums) {
int candidate = nums[0], count = 1;
for (int i = 1; i < nums.length; ++i) {
if (count == 0) {
candidate = nums[i];
count = 1;
} else if (nums[i] == candidate) {
count++;
} else{
count--;
}
}
return candidate;
}
//合并数组冒泡排序实现
public static void merge(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2, 0, nums1, m, n);
// 冒泡排序
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums1.length; j++) {
if (i != j) {
if (nums1[i] < nums1[j]){
int temp = nums1[i];
nums1[i] = nums1[j];
nums1[j] = temp;
}
}
}
}
String result = Arrays.stream(nums1).mapToObj(String::valueOf).collect(Collectors.joining(",", "[", "]"));
System.out.println(result);
}
// public static String longestCommonPrefix(String[] strs) {
// int index = 0;
// StringBuilder temp = new StringBuilder();
// if (strs != null){
// for (int k = 0; k < strs[0].length(); k++) {
// char indexChar = strs[0].charAt(index);
// if (strs.length == 1){
// return strs[0];
// }
// for (int i = 1; i < strs.length; i++) {
// if (strs[i] != ""){
// for (int j = 0; j < 1; j++) {
// if (index >= strs[i].length()){
// return String.valueOf(temp);
// }
// char crrChar = strs[i].charAt(index);
// if (indexChar != crrChar){
// return String.valueOf(temp);
// }
// if (i == strs.length- 1){
// temp.append(crrChar);
// index++;
// }
// }
// } else {
// return "";
// }
// }
// }
// return String.valueOf(temp);
// }
// return "";
// }
/**
* 编写一个函数来查找字符串数组中的最长公共前缀。
* 如果不存在公共前缀,返回空字符串 ""。
* @param strs 数组
* @return 最长公共前缀
*/
public static String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
int length = strs[0].length();
int count = strs.length;
for (int i = 0; i < length; i++) {
char c = strs[0].charAt(i);
for (int j = 1; j < count; j++) {
if (i == strs[j].length() || strs[j].charAt(i) != c) {
return strs[0].substring(0, i);
}
}
}
return strs[0];
}
/**
给你一个数组 nums 和一个值 val你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
*/
public static int removeElement(int[] nums, int val) {
int i = 0;
for (int j = 0; j < nums.length; j++) {
if (nums[j] != val) {
nums[i] = nums[j];
i++;
}
}
return i;
}
/**
* 给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
* 元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
*/
public static int removeDuplicates(int[] nums) {
if (nums.length == 0) return 0;
int i = 1; // 从第二个元素开始检查
for (int j = 1; j < nums.length; j++) {
if (nums[j] != nums[j - 1]) {
nums[i] = nums[j];
i++;
}
}
return i;
}
/**
* 给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
* 判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
* @param nums
* @return
*/
public static boolean canJump(int[] nums) {
int maxReach = 0; // 初始化最远可到达的位置为0
for (int i = 0; i < nums.length; i++) {
if (i > maxReach) {
// 如果当前索引超过了最远可到达的位置,说明无法到达终点
return false;
}
// 更新最远可到达的位置
maxReach = Math.max(maxReach, i + nums[i]);
}
return true;
}
/**
* 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
* @param list1
* @param list2
* @return
*/
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy = new ListNode(0);
ListNode current = dummy;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
current = current.next;
}
if (list1 != null){
current.next = list1;
} else if (list2 != null){
current.next = list2;
}
return dummy.next;
}
/**
*给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
* @param haystack
* @param needle
* @return
*/
public int strStr(String haystack, String needle) {
if (needle.isEmpty()) return -1;
return haystack.indexOf(needle);
}
/**
* 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
*
* 请必须使用时间复杂度为 O(log n) 的算法。
* @param nums
* @param target
* @return
*/
public int searchInsert(int[] nums, int target) {
if (nums.length == 0) return 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] >= target) {
return i;
}
}
return nums.length;
}
/**
* 给你一个字符串 s由若干单词组成单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
*
* 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。
* @param s
* @return
*/
public int lengthOfLastWord(String s) {
if (s.isEmpty()) return 0;
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) != ' ') {
int count = 0;
while (i >= 0 && s.charAt(i) != ' ') {
count++;
i--;
}
return count;
}
}
return 0;
}
/**
* 给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
*
* 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
*
* 你可以假设除了整数 0 之外,这个整数不会以零开头。
* @param digits
* @return
*/
public static int[] plusOne(int[] digits) {
int n = digits.length;
// 从数组的最后一位开始处理进位
for (int i = n - 1; i >= 0; i--) {
if (digits[i] < 9) {
digits[i]++;
return digits;
}
// 如果当前位是9则将其置为0
digits[i] = 0;
}
// 如果所有的数字都是9那么会到这里
// 创建一个新的数组其长度比原数组多1
int[] newNumber = new int[n + 1];
newNumber[0] = 1;
return newNumber;
}
/**
* 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。
*
* 输入为 非空 字符串且只包含数字 1 和 0。
* @param a
* @param b
* @return
*/
public static String addBinary(String a, String b) {
StringBuilder result = new StringBuilder(); // 用于存储结果
int carry = 0; // 进位
int i = a.length() - 1, j = b.length() - 1; // 指向字符串a和b的最后一位
// 当i或j在范围内或有进位时继续循环
while (i >= 0 || j >= 0 || carry == 1) {
int sum = carry; // 当前位的和,初始为进位
// 如果i在范围内加上a的当前位
if (i >= 0) {
sum += a.charAt(i) - '0'; // 将字符转换为数字
i--; // 移动到下一位
}
// 如果j在范围内加上b的当前位
if (j >= 0) {
sum += b.charAt(j) - '0'; // 将字符转换为数字
j--; // 移动到下一位
}
result.append(sum % 2); // 当前位的结果
carry = sum / 2; // 更新进位
}
return result.reverse().toString(); // 反转结果并返回
}
/**
*给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
* 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
* 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
*
* @param x
* @return
*/
public static int mySqrt(int x) {
if (x < 2){
return x;
}
long guess = x / 2;
while (guess * guess > x){
guess = (guess + x/guess)/2;
}
return (int) guess;
}
/**
* 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
* 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
* @param n
* @return
*/
public static int climbStairs(int n) {
if(n < 3)return n;
int dp[]=new int[n+1];
dp[1]=1;
dp[2]=2;
for(int i=3;i<n+1;i++) {
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
/**
* 给定一个已排序的链表的头 head 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
* @param head
* @return
*/
public static ListNode deleteDuplicates(ListNode head) {
ListNode current = head;
while (current!= null && current.next != null){
if (current.val == current.next.val){
current.next = current.next.next;
}else {
current = current.next;
}
}
return head;
}
}

View File

@@ -0,0 +1,14 @@
package com.nbee.solution.solution;
public class test {
public static void main(String[] args) {
ListNode head = new ListNode(1);
head.next = new ListNode(1);
head.next.next = new ListNode(1);
head.next.next.next = new ListNode(2);
ListNode result = Solution.deleteDuplicates(head);
System.out.println(result.toString());
}
}

View File

@@ -1,108 +0,0 @@
package solution;
import java.util.*;
import java.util.stream.Collectors;
public class Solution {
//给定一个字符串 s ,找出其中不含有重复字符的 最长子串 的长度。
public static int lengthOfLongestSubstring(String s) {
// 哈希集合,记录每个字符是否出现过
Set<Character> occ = new HashSet<Character>();
int n = s.length();
// 右指针,初始值为 -1相当于我们在字符串的左边界的左侧还没有开始移动
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.remove(s.charAt(i - 1));
}
while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
// 不断地移动右指针
occ.add(s.charAt(rk + 1));
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
}
//计算最大价格
public static int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) {
return 0;
}
int minPrice = prices[0];
int maxProfit = 0;
for (int price : prices) {
// 更新最小价格
minPrice = Math.min(minPrice, price);
// 计算当前价格的潜在利润并更新最大利润
int potentialProfit = price - minPrice;
maxProfit = Math.max(maxProfit, potentialProfit);
}
return maxProfit;
}
//哈希映射算法Hash Mapping Algorithm用于找出一个数组中的众数majority element
public static int majorityElement(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
// maxNum 表示元素maxCount 表示元素出现的次数
int maxNum = 0, maxCount = 0;
for (int num: nums) {
int count = map.getOrDefault(num, 0) + 1;
map.put(num, count);
if (count > maxCount) {
maxCount = count;
maxNum = num;
}
}
return maxNum;
}
//摩尔投票算法Boyer-Moore Voting Algorithm来找出数组中的众数
public static int majorityElement1(int[] nums) {
int candidate = nums[0], count = 1;
for (int i = 1; i < nums.length; ++i) {
if (count == 0) {
candidate = nums[i];
count = 1;
} else if (nums[i] == candidate) {
count++;
} else{
count--;
}
}
return candidate;
}
//合并数组冒泡排序实现
public static void merge(int[] nums1, int m, int[] nums2, int n) {
int[] nums= new int[m + n];
for (int i = 0; i < m + n; i++) {
if (i < m){
nums[i] = nums1[i];
} else {
nums[i] = nums2[i - m];
}
}
// 冒泡排序
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length; j++) {
if (i != j) {
if (nums[i] < nums[j]){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
}
}
nums1 = nums;
String result = Arrays.stream(nums1).mapToObj(String::valueOf).collect(Collectors.joining(",", "[", "]"));
System.out.println(result);
}
}

View File

@@ -1,21 +0,0 @@
package solution;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public class test {
public static void main(String[] args) {
int[] nums1 = new int[]{1,2,3,0,0,0};
int m = 3;
int[] nums2 = new int[]{2,5,6};
int n = 3;
// int[] nums1 = new int[]{1};
// int m = 1;
// int[] nums2 = new int[]{};
// int n = 0;
Solution.merge(nums1,m,nums2,n);
}
}

View File

@@ -0,0 +1,139 @@
package com.nbee.solution.practice;
import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.DisplayName;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.*;
public class BinarySearchTest {
private int[] nums = {1, 3, 5, 7, 9};
@Test
public void testBinarySearchBasic_Found() {
int[] nums = {1, 3, 5, 7, 9, 11, 13};
int target = 5;
int result = BinarySearch.binarySearchBasic(nums, target);
Assert.assertEquals("Element should be found at index 2", 2, result);
}
@Test
public void testBinarySearchBasic_NotFound() {
int[] nums = {1, 3, 5, 7, 9};
int target = 4;
int result = BinarySearch.binarySearchBasic(nums, target);
Assert.assertEquals("Element should not be found", -1, result);
}
@Test
public void testBinarySearchBasic_EmptyArray() {
int[] nums = {};
int target = 1;
int result = BinarySearch.binarySearchBasic(nums, target);
Assert.assertEquals("Element should not be found in an empty array", -1, result);
}
@Test
public void testBinarySearchBasic_SingleElementArray() {
int[] nums = {1};
int target = 1;
int result = BinarySearch.binarySearchBasic(nums, target);
Assert.assertEquals("Element should be found at index 0", 0, result);
target = 2;
result = BinarySearch.binarySearchBasic(nums, target);
Assert.assertEquals("Element should not be found", -1, result);
}
@Test
public void testBinarySearchBasic_DecreasingArray() {
int[] nums = {9, 7, 5, 3, 1};
int target = 5;
int result = BinarySearch.binarySearchBasic(nums, target);
Assert.assertEquals("Binary search should work on decreasing arrays", 2, result);
}
@Test
public void testBinarySearchAlternativeFound() {
// Test that the method correctly returns the index of an existing element
int target = 7;
int result = BinarySearch.binarySearchAlternative(nums, target);
assertEquals(3, result, "The target should be found at index 3");
}
@Test
public void testBinarySearchAlternativeNotFound() {
// Test that the method correctly returns -1 when the element is not present
int target = 4;
int result = BinarySearch.binarySearchAlternative(nums, target);
assertEquals(-1, result, "The target should not be found");
}
@Test
public void testBinarySearchAlternativeWithEmptyArray() {
// Test with an empty array
int[] emptyNums = new int[]{};
int target = 1;
int result = BinarySearch.binarySearchAlternative(emptyNums, target);
assertEquals(-1, result, "The target should not be found in an empty array");
}
@Test
public void testBinarySearchAlternativeWithSingleElement() {
// Test with a single element array
int[] singleNums = new int[]{5};
int target = 5;
int result = BinarySearch.binarySearchAlternative(singleNums, target);
assertEquals(0, result, "The target should be found at index 0 in a single-element array");
}
@Test
@DisplayName("Test Binary Search Java")
public void testBinarySearchJava() {
int[] nums = {1, 3, 5, 7, 9};
int target = 4;
int result = Arrays.binarySearch(nums, target);
if (result < 0) {
int insertIndex = Math.abs(result + 1);
System.out.println("nums: " + Arrays.toString(nums));
System.out.println("insertIndex: " + insertIndex);
int[] newNums = new int[nums.length + 1];
//第一次拷贝
System.arraycopy(nums, 0, newNums, 0, nums.length);
System.out.println("newNums: " + Arrays.toString(newNums));
newNums[insertIndex] = target;
// 第二次拷贝
System.arraycopy(nums, insertIndex, newNums, insertIndex + 1, nums.length - insertIndex);
System.out.println("newNums: " + Arrays.toString(newNums));
}
System.out.println("result: " + result);
assertEquals(-3, result, "The target should not be found");
}
@Test
public void testBinarySearchLeftMost() {
int[] nums = new int[]{1, 3, 3, 5, 7};
assertEquals(0, BinarySearch.binarySearchLeftMost(nums, 1));
assertEquals(1, BinarySearch.binarySearchLeftMost(nums, 3));
}
@Test
public void testBinarySearchRightMost() {
int[] nums = new int[]{1, 3, 3, 5, 5, 5, 5, 5, 7};
assertEquals(0, BinarySearch.binarySearchRightMost(nums, 1));
assertEquals(2, BinarySearch.binarySearchRightMost(nums, 3));
assertEquals(7, BinarySearch.binarySearchRightMost(nums, 5));
}
@Test
public void testSearchRange() {
int[] nums = {5, 7, 7, 8, 8, 10};
int[] nums1 = {1};
assertArrayEquals(new int[]{1,2}, BinarySearch.searchRange(nums, 7), "The result should be [1, 2]" );
assertArrayEquals(new int[]{3,4}, BinarySearch.searchRange(nums, 8), "The result should be [3, 4]" );
assertArrayEquals(new int[]{-1, -1}, BinarySearch.searchRange(nums, 6), "The result should be [-1, -1]");
assertArrayEquals(new int[]{0, 0}, BinarySearch.searchRange(nums1, 1), "The result should be [0, 0]");
}
}

View File

@@ -0,0 +1,79 @@
package com.nbee.solution.practice;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
class DynamicArrayTest {
private DynamicArray dynamicArray;
@BeforeEach
public void setUp() {
dynamicArray = new DynamicArray();
}
@Test
public void testAddListInitial() {
dynamicArray.addList(1);
dynamicArray.addList(3);
dynamicArray.addList(5);
dynamicArray.add(1, 7);
for (int i = 0; i < 4; i++) {
System.out.println(dynamicArray.get(i));
}
}
@Test
public void test01() {
dynamicArray.addList(1);
dynamicArray.addList(3);
dynamicArray.addList(5);
dynamicArray.add(1, 7);
dynamicArray.forEach(element -> {
System.out.println(element);
});
}
@Test
public void test02() {
dynamicArray.addList(1);
dynamicArray.addList(3);
dynamicArray.addList(5);
dynamicArray.add(1, 7);
for (Integer element : dynamicArray) {
System.out.println(element);
}
}
@Test
public void test03() {
dynamicArray.addList(1);
dynamicArray.addList(3);
dynamicArray.addList(5);
dynamicArray.add(1, 7);
dynamicArray.stream().forEach(element -> {
System.out.println(element);
});
}
@Test
public void test04() {
dynamicArray.addList(1);
dynamicArray.addList(3);
dynamicArray.addList(5);
dynamicArray.add(1, 7);
int removed =dynamicArray.remove(1);
System.out.println("removed: " + removed);
for (Integer element : dynamicArray) {
System.out.println(element);
}
}
@Test
public void test05() {
for (int i = 0; i < 9; i++) {
dynamicArray.addList(i);
}
System.out.println(dynamicArray.toString());
assertIterableEquals(List.of(0, 1, 2, 3, 4, 5, 6, 7, 8), dynamicArray, "List should be equal");
}
}

View File

@@ -0,0 +1,25 @@
package com.nbee.solution.practice;
import org.junit.Test;
public class SinglyLinkedListTest {
private SinglyLinkedList list = new SinglyLinkedList();
@Test
public void singlyLinkedListAddFirstTest(){
list.addFirst(1);
list.addFirst(3);
list.addFirst(5);
list.addFirst(6);
list.loop0(i -> System.out.println(i + " "));
}
@Test
public void singlyLinkedListIteratorTest(){
list.addFirst(1);
list.addFirst(3);
list.addFirst(5);
list.addFirst(6);
for (Integer value: list) {
System.out.println(value);
}
}
}