algorism

顺序查找

分治算法

回溯、分治、和动态规划算法可以规划为一类,都会涉及到递归。

动态规划是一类算法问题,

动态规划

递归求x的n次方

package Temp;

import java.util.Scanner;

/*
 * @Author: jun
 * @Date:2023/1/30 0:03
 * @概述:
 */
public class niuke004 {
    //求x的n次方

     static int function01(int x, int n){
        int result = 1;//把结果赋值为1是为了表示所有的数的0次方都是1
        for (int i = 0; i < n; i++) {//循环n次中每次的result都是取了n-1次方的结果
            result = result * x;
        }
        return result;//返回x的n次方
    }

    static int recursive(int x, int n){
         if (n == 0){
             return 1;
         }
         return x*recursive(x,n-1);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        //使用普通的for循环计算x的n次方结果
        System.out.println("使用普通的for循环计算x的n次方结果");
        System.out.println("输入x的值:");
        int x = scanner.nextInt();
        System.out.println("输入n的值:");
        int n = scanner.nextInt();

        long start = System.nanoTime();
        System.out.println("result="+function01(x,n));
        long end = System.nanoTime();
        System.out.println("时间消耗"+(end-start));
        System.out.println("_________________");

        //使用递归的算法解决该题
        System.out.println("使用递归的算法解决该题");
        long start02 = System.nanoTime();
        System.out.println("recursive result="+recursive(x,n));
        long end02 = System.nanoTime();
        System.out.println("时间消耗"+(end02-start02));

    }

}

有序数组的平方排列

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 8:32
 * @概述:
 */
public class niuke005 {

    //有序数组的平方排列
    static class solution{
        public int[] sortSquares(int[] nums){
            int right = nums.length-1;//定义右指针
            int left = 0;//定义左指针
            int[] result = new int[nums.length];//新建一个数组用于返回排序后结果,并且大小等于原需排列的数组
            int index = result.length-1;//给新建的数组也定义一个指针,让它从最后一位开始移动,返回比较后的较大值
            while(left<=right){//常规的双指针的条件就是左指针与右指针交错
                //每次比较是用平方后的值来比较
                if (nums[left]*nums[left] > nums[right]*nums[right]){
                    //将大的left添入新数组的右边,
                    result[index--] = nums[left]*nums[left];
                    ++left;//将原数组比较的左指针右移,right不变
                } else {
                    //相反的
                    result[index--] = nums[right]*nums[right];
                    --right;
                }
            }


            return result;
        }
    }

    public static void main(String[] args) {

        int[] arr = {-1,2,3,5,8,17};
        solution solution = new solution();
        int[] ints = solution.sortSquares(arr);
        for (int i:ints
             ) {
            System.out.println(i);
        }
    }

}

前n项和的时间复杂度

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 9:01
 * @概述:
 */
public class temp006 {

    //前n项和的时间复杂度
    //1+2+3+···+100
    static int solution01(int n){
        int sum = 0;
        while(n>0){
            sum+=n;
            n--;
        }
        return sum;
    }

    //设计时间复杂度为O(1)的算法
    static int solution02(int n){
        return n*(n+1)/2;
    }

    //解法三


    public static void main(String[] args){
        long stime = System.nanoTime();
        System.out.println(solution01(100));
        long etime = System.nanoTime();

        long time01 = System.nanoTime();
        System.out.println(solution02(100));
        long time02 = System.nanoTime();

        System.out.println(etime-stime);
        System.out.println(time02-time01);
    }
}

两个数组的交集

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 13:24
 * @概述:
 */

import java.util.HashSet;

/**
 * 两个数组的交集
 * 题意:给定两个数组,编写一个函数来计算它们的交集
 */
public class temp008 {
    public static int[] intersection(int[] nums1,int[] nums2){
        //首先判断这两个数组是否是空的,如果有一方是空的就直接放回一个空数组
        if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0){
            return new int[0];
        }
        //新建两个hashset
        HashSet<Object> set1 = new HashSet<>();
        HashSet<Object> resSet = new HashSet<>();
        //遍历数组set1
        for (int i:nums1) {
            set1.add(i);
        }
        //遍历数组2的过程中判断哈希表set1中是否存在该元素
        for ( int i:nums2){
            if (set1.contains(i)){
                resSet.add(i);
            }
        }
        return resSet.stream().mapToInt(x -> (int) x).toArray();
    }

    public static void main(String[] args) {
        int[] arr1 = {1,2,3,4,5,5};
        int[] arr2 = {1,5};

        for (int i: intersection(arr1,arr2)
             ) {
            System.out.println(i);
        }
    }
}


快乐数

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 13:40
 * @概述:
 */

import java.util.HashSet;
import java.util.Set;

/**
 * 快乐数
 * 编写一个算法来判断一个数是否是快乐数
 * 快乐数的定义:对于一个正整数,
 * 每一次将该数替换为它每一个位置上的数字的平方和,
 * 然后重复这个过程直到这个数变为一,也可能是无限循环
 * 但最终变不到一,如果可以变为一,那么这个数就是快乐数。
 */
public class temp009 {


    //获取每位数
    static int getNextNumber(int n){
        int res = 0;//返回值
        while(n>0){
            int temp = n%10;//取得一位数
            res += temp*temp;//每位数都要进行平方求其值
            n = n / 10;//相当于末尾位取出
            System.out.println(temp);
        }
        return res;
    }

    public static void main(String[] args) {
        getNextNumber(113);

        int n = 123;
        Set<Integer> record = new HashSet<>();
        while(n!=1&&!record.contains(n)){
            record.add(n);
            n = getNextNumber(n);
        }
        System.out.println(n);
    }
}

两数之和

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 16:15
 * @概述:
 */

import java.util.HashMap;

/**
 * 两数之和
 *
 */
public class temp010 {

    static int[] twoSum(int[] nums,int target){
        int[] res = new int[2];//返回值为一个两个空间大小的数组
        if (nums == null || nums.length == 0){
            return res;
        }
        HashMap<Integer, Integer> map = new HashMap<>();//新建一个哈希表,键和值都是整型
        for (int i = 0; i < nums.length; i++) {
            int temp = target - nums[i];//遍历当前元素,并在map中寻找是否有匹配的数
            if(map.containsKey(temp)){
                res[1] = i;
                res[0] = map.get(temp);
                break;
            }
            map.put(nums[i],i);//每次循环都把遍历过的数放进map
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5,6};
        int target = 10;
        int[] ints = twoSum(arr, target);
        for (int i :
                ints) {
            System.out.println(i);
        }
    }
}

四数相加

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 16:47
 * @概述:
 */

import java.util.HashMap;
import java.util.Map;

/**
 * 四数相加
 * 给定四个包含整数的数组列表A,B,C,D,计算有多少个元组(i,j,k,l),
 * 使A[i]+B[j]+C[k]+D[I]=0
 */
public class temp011 {
    static int fourSumCount(int[] nums1,int[] nums2,int[] nums3,int[] nums4){
        Map<Integer,Integer> map = new HashMap<>();
        int temp;
        int res = 0;
        //统计两个数组中的元素之和,同时统计出现的次数,放入map
        for (int i:nums1){
            for (int j :
                    nums2) {
                temp = j + i;
                if (map.containsKey(temp)){
                    map.put(temp,map.get(temp)+1);
                }else{
                    map.put(temp,1);
                }
            }
        }
        //统计剩余的两个元素的和,在map中找是否存在相加为0的情况,同时记录次数
        for (int i :
                nums3) {
            for (int j :
                    nums4) {
                temp = i + j;
                if (map.containsKey(0-temp)){
                    res += map.get(0 - temp);
                }
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int[] arr1 = {-1,2,3,4};
        int[] arr2 = {1,-2,3,4};
        int[] arr3 = {1,2,-3,4};
        int[] arr4 = {1,2,3,-4};

        int i = fourSumCount(arr1, arr2, arr3, arr4);

        System.out.println(i);//i个元组

    }
}

三数之和

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/17 17:30
 * @概述:
 */

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 三数之和
 * 给定一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a+b+c=0
 * 需要找出不可以重复的三元组。
 *
 * 总共三个数:i,left,right
 * i是nums里遍历的元素,重复了的话就直接跳过去
 * 虽然不能有重复的三元组,但三元组内的元素是可以重复
 *
 * left与right的去重
 */
public class temp012 {

    static List<List<Integer>> threeSum(int[] nums){
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);//将数组排序
        //求a + b + c = 0;
        //a = nums[i],b = nums[left], c = nums[right]
        for (int i = 0; i < nums.length; i++) {
            //排序之后如果第一个元素大于零,则说明无论如何组合都不可能三个数和为0
            if (nums[i]>0){
                return result;
            }

            if (i > 0 &&nums[i] == nums[i-1]){
                continue;//去重a
            }

            int left = i+1;//左指针起始位置
            int right = nums.length-1;//右指针至于最右侧
            while(right>left){
                int sum = nums[i] + nums[left] + nums[right];
                if (sum>0){
                    right--;
                }else if (sum < 0){
                    left++;
                }else{
                    result.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    //去重逻辑应该放在找到一个三元组之后,对b和c去重
                    while(right>left&&nums[right] == nums[right-1])right--;
                    while(right>left&&nums[right] == nums[left+1])left--;

                    right--;
                    left++;
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] arr = {-1,0,1,2,-1,-4};

        List<List<Integer>> lists = threeSum(arr);
        System.out.println(lists);
    }
}

反转字符串

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/18 10:19
 * @概述:
 */

/**
 * 反转字符串
 * 编写一个函数,作用是将输入的字符串反转过来,输入字符串以字符数组char[]的形式给出
 * 要求是不使用额外的数组分配空间,你必须原地修改数组
 *
 */
public class temp013 {

    static char[] reverseString(char[] s){
        int l = 0;
        int r = s.length - 1;
        while(l<r){
            s[l] ^= s[r];//构造a^b,并放在a中
            s[r] ^= s[l];//将a^b 这一结果再^b,此时b = a,a = a^b
            s[l] ^= s[r];//a^b的结果再^a,存入a中,此时b = a,a=b
            //完成交换后移动两个指针
            l++;//左指针右移
            r--;//右指针左移
        }
        return s;
    }

    public static void main(String[] args) {
        char[] arr = {'A','B','C','D'};
        char[] chars = reverseString(arr);
        System.out.println(chars);
    }
}

反转字符串II

package Temp;

/*
 * @Author: jun
 * @Date:2023/2/18 10:50
 * @概述:
 */

/**
 * 反转字符串II
 * 给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k个字符中的前k个字符
 * 如果剩余字符小于k个,则将剩余字符全部反转
 * 如果剩余字符小于2k但大于或等于k个,则反转前k个字符,其余字符保持原样。
 */
public class temp014 {

    static String reverseStr(String s,int k){
        StringBuffer res = new StringBuffer();
        int length = s.length();
        int start = 0;
        while(start < length){
            //找到每次需要反转得中点k,还有末尾2k
            StringBuffer temp = new StringBuffer();//新建一个可变字符串stringBuffer
            //与length进行判断,如果大于length了,那就将其置为length
            int firstK = (start + k >length)?length : start+k;
            int secondK = (start + (2*k)>length)?length : start +(2*k);

            //无论start所处的位置,至少会反转一次
            temp.append(s.substring(start,firstK));//获取从start到firstK的字符
            res.append(temp.reverse());//使用stringBuffer自带的反转方法反转

            //如果firstK到secondK之间有元素,这些元素直接放入res里即可
            if (firstK < secondK){
                res.append(s.substring(firstK,secondK));
            }
            start += (2*k);//当length足够时,更改start的位置为2k

        }
        return res.toString();
    }

    public static void main(String[] args) {
        int target = 6;
        String chars = "adadsfdsvfbsbsrtgbr";
        String s = reverseStr(chars, target);
        System.out.println(s);
    }
}

代码优质自学平台:代码随想录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值