import uitls.Node;
import java.util.*;
public class test_02_10 {
//爬楼梯 10 采取递归 3 test(n-1)+test(n-2)
public static int test1(int n){
if (n==1){
return 1;
}
if (n==2){
return 2;
}
return test1(n-1)+test1(n-2);
}
//采取动态规划
public static void test2(int n){
//1:设置dp数组
int[] dp = new int[n+1];
//2:设置初始值
dp[0]=0;
dp[1]=1;
dp[2]=2;
//3:设置状态转移规则
for (int i=0;i<dp.length;i++){
if (i>2){
dp[i]=dp[i-1]+dp[i-2];
}
}
System.out.println(Arrays.toString(dp));
}
//采取hashMap来保存已经求解过的值不求解
public static void test3(int n, HashMap<Integer, Integer> hashMap){
if (n==1){
hashMap.put(1,1);
return;
}
if (n==2){
hashMap.put(2,2);
return;
}
if (hashMap.get(n)!=null){
//表示已有
return;
}else{
//没有的话
test3(n-1,hashMap);
test3(n-2,hashMap);
hashMap.put(n, hashMap.get(n-1)+hashMap.get(n-2));
}
}
//斐波拉契数列-递归
public static int test4(int n){
if (n==0){
return 0;
}
if (n==1){
return 1;
}
return test4(n-1)+test4(n-2);
}
//斐波拉契数列-hash+递归
public static void test5(int n, HashMap<Integer, Integer> hashMap){
if (n==0){
hashMap.put(0,0);
return;
}
if (n==1){
hashMap.put(1,1);
return;
}
if (hashMap.get(n)!=null){
return;
}else{
test5(n-1,hashMap);
test5(n-2,hashMap);
hashMap.put(n,hashMap.get(n-1)+hashMap.get(n-2));
}
}
//斐波拉契数列-规划
public static void test6(int n){
//1:建立dp数组
int[] dp=new int[n+1];
//2:初始化dp数组
dp[0]=0;
dp[1]=1;
//3:状态转移方程
for (int i=2;i<dp.length;i++){
dp[i]=dp[i-1]+dp[i-2];
}
}
//dp数组优化
public static void test7(int n){
int a=0;
int b=1;
for (int i=2;i<=n;i++){
int temp=a;
a=b;
b=b+temp;
}
System.out.println(b);
}
//两数之和 等于 target-暴力破解
public static void test8(int[] nums, int target){
int res1=-1;
int res2=-1;
for (int i=0;i<nums.length-1;i++){
for (int j=i+1;j<nums.length;j++){
if (nums[i]+nums[j]==target){
res1=i;
res2=j;
return;
}
}
}
}
//两数之和-双指针法 7 4 8 9
public static void test9(int[] nums, int target){
//1:先排序
Arrays.sort(nums);
//2:再进行查找
int i=0;
int j=nums.length-1;
while (i<j){
if (nums[i]+nums[j]<target){
i++;
}else if (nums[i]+nums[j]>target){
j--;
}else{
return;
}
}
}
//快速排序
public static void test10(int[] nums, int left, int right){
if (left>=right){
return;
}
int target = nums[left];
int i=left;
int j=right;
while (i<=j){
if (nums[i]<=target){
i++;
}else if (nums[j]>target){
j--;
}else {
swap(nums, i, j);
}
}
swap(nums,left,j);
test10(nums, left, j-1);
test10(nums, j+1,right);
}
public static void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
public static void test11(int[] nums, int target){
//采取hashMap形式进行求解
HashMap<Integer, Integer> map = new HashMap<>();
for (int i=0;i<nums.length;i++){
if (map.get(target-nums[i])==null){
map.put(nums[i],i);
}else{
System.out.println(Arrays.asList(i,map.get(target-nums[i])));
return;
}
}
}
//合并两个有序数组-采取一个新数组进行存储
public static void test12(int[] num1, int[] num2){
//两个数组长度
int n=num2.length;
int m=num1.length-n;
int[] arr = new int[m+n];
int k=0;
//进行合并
int i=0;
int j=0;
while (i<m&&j<n){
if (num1[i]<num2[j]){
arr[k]=num1[i];
k++;
i++;
}else{
arr[k]=num2[j];
k++;
j++;
}
}
while (i<m){
arr[k]=num1[i];
k++;
i++;
}
while (j<n){
arr[k]=num2[j];
k++;
j++;
}
}
//合并两个有序数组-不采取一个新数组-类似与直接插入法
public static void test13(int[] num1, int[] num2){
//逐步遍历num2 将其往后移动
int n=num2.length;
int m=num1.length-n;
for (int i=0;i<num2.length;i++){
int j=m-2;
for (;j>=0;j++){
if (num2[i]<num1[j]){
num1[j+1]=num1[j];
}else{
break;
}
}
num1[j]=num2[i];
}
}
public static void test14(int[] num1, int[] num2){
int total = num1.length;
int n = num2.length;
int m = total-n;
int k=total-1;
int i=m-1;
int j=n-1;
while (i>=0&&j>=0){
if (num1[i]>num2[j]){
num1[k--]=num1[i--];
}else{
num1[k--]=num2[j--];
}
}
while (i>=0){
num1[k--]=num1[i--];
}
while (j>=0){
num1[k--]=num2[j--];
}
}
//移动零-将所有的0放置到末尾(先不考虑元素之间的相对位置)
public static void test15(int[] nums){
int i=0;
int j=nums.length-1;
while (i<=j){
if (nums[i]!=0){
i++;
}else if(nums[j]==0){
j--;
}else{
swap(nums, i, j);
}
}
System.out.println(Arrays.toString(nums));
}
//移动零-保持元素之间的相对位置-两个指针
public static void test16(int[] nums){
//i用来指向0
int i=0;
//j用来指向非0
int j=0;
int count =0;
//找出非0的数
for (int k=0;k<nums.length;k++){
if (nums[k]!=0){
count++;
}
}
while (i<count){
if (nums[i]!=0){
i++;
}else{
//找到了i 找下一个j
j=i;
while (j<nums.length){
if (nums[j]!=0)break;
else j++;
}
swap(nums, i, j);
}
}
System.out.println(Arrays.toString(nums));
}
//更优的方式
public static void test17(int[] nums){
int j=0;
for (int i=0;i<nums.length;i++){
if (nums[i]!=0){
nums[j++]=nums[i];
}
}
for (int i=j;i<nums.length;i++){
nums[i]=0;
}
System.out.println(Arrays.toString(nums));
}
//找出数组中消失的数字-采取hash
public static void test18(int[] nums){
HashMap<Integer, Integer> map = new HashMap<>();
//将所有元素都放进hash中
for (int i=0;i<nums.length;i++){
map.put(nums[i],1);
}
List<Integer> ls = new ArrayList<>();
for (int i=1;i<=nums.length;i++){
if (map.get(i)==null){
ls.add(i);
}
}
System.out.println(ls);
}
//找出数组中消失的数字-不使用额外的数组
//[1,1,2]
//采取数组本身的特性 没有出现的下标我就不动
public static void test19(int[] nums){
for (int i=0;i<nums.length;i++){
if (nums[Math.abs(nums[i])-1]>0){
nums[Math.abs(nums[i])-1] = -1*nums[Math.abs(nums[i])-1];
}
}
List<Integer> ls = new ArrayList<>();
for (int i=0;i<nums.length;i++){
if (nums[i]>0){
ls.add(i+1);
}
}
System.out.println(ls);
}
//前面有一道题 合并两个有序数组
//合并两个有序链表
public static Node test20(Node root1, Node root2){
Node p1=root1;
Node cur1 = p1;
Node p2=root2;
Node cur2 = p2;
while (p1!=null&&p2!=null){
//小于
if (p1.getData()<p2.getData()){
cur1 = p1;
p1=p1.getNext();
}else {
cur2 = p2;
p2 = cur2.getNext();
//插入p1头
if (p1 == cur1) {
cur2.setNext(p1);
root1 = cur2;
} else {
//插入p1身体
cur2.setNext(p1);
cur1.setNext(cur2);
}
}
}
if (p2!=null){
cur1.setNext(p2);
}
return root1;
}
//两个单链表的公共节点
public static Node test21(Node root1, Node root2){
Node p1 = root1;
int count1=0;
Node p2 = root2;
int count2=0;
//获得两个链表的长度
while (p1!=null){
p1 = p1.getNext();
count1++;
}
while (p2!=null){
p2 = p2.getNext();
count2++;
}
int x = count1-count2;
p1=root1;
p2=root2;
if (x>0){
while (x-->0){
p1=p1.getNext();
}
}else{
x=-x;
while (x++<0){
p2=p2.getNext();
}
}
while (p1!=null&&p2!=null){
if (p1==p2){
break;
}else{
p1=p1.getNext();
p2=p2.getNext();
}
}
return p1;
}
//判断单链表是否存在回文序列
public static void test22(Node root){
//将节点依次入栈
Stack<Node> stack = new Stack<>();
Node p = root;
while (p!=null){
stack.push(p);
}
boolean flag = true;
p = root;
while (!stack.empty()){
//如果存在不相等的话就之间出栈
if (stack.pop().getData()!=p.getData()){
flag = false;
break;
}else{
p=p.getNext();
}
}
System.out.println(flag);
}
public static void test23(Node root){
//先找出链表的长度
int count=0;
Node p = root;
while (p!=null){
count++;
p=p.getNext();
}
p=root;
//将一半入栈
Stack<Node> stack = new Stack<>();
for (int i=0;i<count/2;i++){
stack.push(p);
p=p.getNext();
}
if (count%2!=0){
p=p.getNext();
}
boolean flag = true;
while (!stack.isEmpty()){
if (stack.pop().getData()!=p.getData()){
flag=false;
break;
}
p=p.getNext();
}
}
//合并两个升序列表
public static Node test24(Node root1, Node roo2){
Node p1=root1;
Node p2=roo2;
Node root = new Node();
while (p1!=null&&p2!=null){
if (p1.getData()<p2.getData()){
root.setNext(new Node(p1.getData()));
p1=p1.getNext();
}else{
root.setNext(new Node(p2.getData()));
p2=p2.getNext();
}
}
while (p1!=null){
root.setNext(new Node(p1.getData()));
p1=p1.getNext();
}
while (p2!=null){
root.setNext(new Node(p2.getData()));
p2=p2.getNext();
}
return root.getNext();
}
//删除链表中重复元素-升序排列删除头节点
public static Node test25(Node root){
Node p=root;
Node q=p;
while (q!=null){
q=p.getNext();
if (p.getData()==q.getData()){
//寻咋下一个不相等的元素
while (q!=null&&q.getData()==p.getData()){
q=q.getNext();
}
//找到以后
p.setNext(q);
}
p=p.getNext();
}
return root;
}
//时间复杂度为n的方式
public static Node test26(Node root1){
Node root = root1;
if (root==null||root.getNext()==null){
return root;
}
while (root.getNext()!=null){
if (root.getData()==root.getNext().getData()){
root.setNext(root.getNext().getNext());
}else{
root=root.getNext();
}
}
return root1;
}
//采取递归的形式进行遍历
public static void test27(Node root){
if (root==null||root.getNext()==null){
return;
}
if (root.getData()==root.getNext().getData()){
root.setNext(root.getNext().getNext());
}else{
root=root.getNext();
}
test27(root);
}
//环形链表 判断是不是环形链表
public static void test28(Node root){
//快慢指针遍历
Node slow = root;
Node quick = root;
boolean flag = false;
while (quick!=null&&quick.getNext()!=null){
slow=slow.getNext();
quick=quick.getNext().getNext();
if (slow==quick){
flag=true;
}
}
}
//环形链表 找出环形链表的入口
public static Node test29(Node root){
//先找到meet点
//快慢指针遍历
Node slow = root;
Node quick = root;
while (quick!=null&&quick.getNext()!=null){
slow=slow.getNext();
quick=quick.getNext().getNext();
}
slow = root;
while (slow!=quick){
slow=slow.getNext();
quick=quick.getNext();
}
return slow;
}
//反转链表
public static Node test30(Node head){
if (head==null||head.getNext()==null){
return head;
}
Node p=head;
Node q=p.getNext();
Node r=q.getNext();
//头节点设置为null
p.setNext(null);
while (q!=null){
q.setNext(p);
p=q;
q=r;
if (r!=null){
r=r.getNext();
}
}
return head;
}
//反转链表优化遍历
public static void test31(Node head){
Node pre = null;
Node p = head;
while (p!=null){
Node next = p.getNext();
p.setNext(pre);
pre=p;
p=next;
}
}
//递归
public static Node test32(Node head){
if (head==null||head.getNext()==null){
return head;
}
Node newHead = test32(head.getNext());
head.getNext().setNext(head);
head.setNext(null);
return newHead;
}
//链表的中间节点
public static List<Node> test33(Node head){
Node slow = head;
Node quick=head;
Node cur = slow;
while (quick!=null&&quick.getNext()!=null){
cur = slow;
slow=slow.getNext();
quick=quick.getNext();
}
if (quick==null){
return Arrays.asList(cur, slow);
}
if (quick.getNext()==null){
return Arrays.asList(slow);
}
return null;
}
//返回链表的倒数第k个节点
public static Node test34(Node node,int k){
Stack<Node> stack = new Stack<>();
Node p = node;
while (p!=null){
stack.push(p);
p=p.getNext();
}
while (!stack.isEmpty()&&k-->1){
stack.pop();
}
if (stack.isEmpty()){
return null;
}
return stack.pop();
}
//字符串解码
public static String test35(String s){
Stack<String> stack = new Stack<>();
String str = "=";
int d = 0;
for (int i=0;i<s.length();i++){
//字母
if (Character.isLetter(s.charAt(i))){
str += s.charAt(i);
}
//数字
if (Character.isDigit(s.charAt(i))){
d = Integer.parseInt(s.charAt(i)+"");
}
//左括号 入栈
if (s.charAt(i)=='['){
stack.push(d+"-"+str);
str = "=";
}
//右括号 出栈
if (s.charAt(i)==']'){
String content = stack.pop();
String[] ls = content.split("-");
String temp = "";
//将里面的内容汇聚
for (int k=0;k<Integer.parseInt(ls[0]);k++){
temp += str;
}
str = ls[1]+temp;
}
}
return str.substring(1);
}
public static void main(String[] args) {
}
}
2025年2月10日40道算法题
最新推荐文章于 2026-08-22 14:49:29 发布

7939

被折叠的 条评论
为什么被折叠?



