个人算法重刷记录

Posted 流楚丶格念

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了个人算法重刷记录相关的知识,希望对你有一定的参考价值。

文章目录

对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符保证字符串中有重复的字符,字符串的长度小于等于 500

代码如下:

package com.yyl.algorithm.questions;

public class FirstRepeat 
    public static void main(String[] args) 
        System.out.println(findFirstRepeat("pmedmitjtckhxwhvpwemznh mhzhpueainchqrftkm" +
                "bjlradhmjekcqzansyzkvqhwnrdgzdbzewdmxkzrscik daugbvygntrifnolehdtrqjlasofuvz" +
                "eijbmzehkxknmjekcxswqldknysfsxr qaqzp", 152));
    

    /**
     * 查找第一个重复的字符
     * @param A 字符串
     * @param n 字符串长度
     * @return 第一个重复的字符
     */
    public static char findFirstRepeat(String A, int n) 
        char[] chars = A.toCharArray();
        for (int i=0;i<n;i++)
            // 重复字符的下标
            int index =0;
            // 当前字符的数量
            int num=0;
            // 对于每一个值,都需要从前开始遍历
            while (index<i)
                if (chars[i]==chars[index])
                    num++;
                
                index++;
            
            // 如果该值出现了两次,说明重复了
            if (num>0)
                return chars[i];
            
        

        // 如果只能到末尾,说明没有重复的
        return '×';
    

实现拷贝数组函数

代码如下:

package com.yyl.algorithm.questions;

import java.util.Arrays;

public class CopyArray 
    public static void main(String[] args) 
        int[] arr1 = 10, 20, 30, 40, 50;
        int[] arr2 = CopyArrays(arr1);
        System.out.println(Arrays.toString(arr2));
    

    private static int[] CopyArrays(int[] arr) 
        int[] arr2 = new int[arr.length];
        for (int i = 0; i < arr.length; i++) 
            arr2[i] = arr[i];
        
        return arr2;
    

写一排序算法,输入 10 个数字,以逗号分开,可根据参数选择升序或者 降序排序,须注明是何种排序算法

代码如下:

package com.yyl.algorithm.questions;

import java.util.Scanner;

public class SortDemo 

    /**
     * 将String类型的数组转换成int类型的数组
     *
     * @param s
     * @return
     */
    private static int[] getInt(String[] str) 
        int arr[] = new int[str.length];
        for (int i = 0; i < str.length; i++) 
            arr[i] = Integer.parseInt(str[i]);
        
        return arr;
    

    /**
     * 给定的字符串使用,号分隔
     *
     * @param str
     * @return
     */
    private static String[] split(String str) 
        String[] strSplit = str.split(",");
        return strSplit;
    

    /**
     * 排序算法
     *
     * @param arr
     */
    public static void sort(int[] arr) 
        // 很久没写冒泡了,先冒个泡
        for (int i = 0; i < arr.length - 1; i++) 
            for (int j = 0; j < arr.length - 1 - i; j++) 
                if (arr[j] > arr[j + 1]) 
                    swap(arr, j, j + 1);
                
            
        
    

    // 很久没写快排了,快个排
    public static void quicksort(int[] arr, int left, int right) 
        // 递归终止条件
        if (left > right) 
            return;
        
        int i = left, j = right;
        // 以左边为基准
        while (i < j) 
            while (i < j && arr[j] >= arr[left]) 
                j--;
            
            while (i < j && arr[i] <= arr[left]) 
                i++;
            
            swap(arr, i, j);
        
        // 交换i的位置与left基准
        swap(arr, i, left);
        // 再快排左右
        quicksort(arr, left, i - 1);
        quicksort(arr, i + 1, right);
    

    /**
     * 两数交换的方法
     *
     * @param arr 数组
     * @param x   数组中元素的下标
     * @param y   数组中元素的下标
     */
    public static void swap(int[] arr, int x, int y) 
        int temp = arr[x];
        arr[x] = arr[y];
        arr[y] = temp;
    


    public static void main(String[] args) 
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数字串,每个数字以逗号分隔 ");
        String str = input.next();
        //调用方法
        String[] s = split(str);//使用逗号分隔
        int[] arr = getInt(s);//调有获得整型数组的方法
        // sort(arr);//调用排序的方法
        quicksort(arr, 0, s.length-1);//调用排序的方法
        for (int i : arr) 
            System.out.print(i + "\\t");
        
    


判断字符串是否是这样的组成的,第一个字母,后面可以是字母、数字、下划线、总长度为 5-20

代码如下:

package com.yyl.algorithm.questions;

import java.util.Scanner;

public class StringDemo 
    public static void main(String[] args) 
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个字符串,第一个字符必须是字母:");

        String str = input.next();
        if (str.length() < 5 || str.length() > 20) 
            System.out.println("对不起,字符串的长度必须在5-20之 间!");
         else 
            char[] ch = str.toCharArray();
            //判断第一个字符是否是 字母
            if (Character.isLetter(ch[0])) 
                for (int i = 1; i < ch.length; i++) 
                    if (!Character.isLetterOrDigit(ch[i]) && ch[i] != '_') 
                        System.out.println("字符串不符合要求");
                        break;
                    
                
            
        
    

已排好序的数组 A,一般来说可用二分查找可以很快找到,现有一特殊数组 A,它是循环递增的,如 a[]=17, 19 ,20, 25, 1, 4, 7, 9,在这样的数组中找一元素,看看是否存在。请写出你的算法,必要时可写伪代码,并分析其空间,时间复杂度

**思路说明:**循环递增数组有这么一个性质:以数组中间元素将循环递增数组划分为两部 分,则一部分为一个严格递增数组,而另一部分为一个更小的循环递增数组。

当中间元素大于首元素时,前半部分为严格递增数组,后半部分为循环递增数组;

  • 例如:【3 4 5 6 7 1 2】

当中间元素小于首元素时,前半部分为循环递增数组;后半部分为严格递增数组。

  • 例如:【6 7 1 2 3 4 5】

记要检索的元素为 e,数组的首元素为 a[low],中间元素为 a[mid],末尾元素为 a[high]。

那么我们可以总结出:

  • 当 e 等于 a[mid] 时,直接返回 mid 的值即可;

  • 当 e 不等于 a[mid] 时:

    • a[mid] > a[low],即数组前半部分为严格递增数组,后半部分为循环递增数组时,若 key 小于 a[mid]并且不小于 a[low]时,则 key 落在数组前半部分;否则,key 落在数组后半部分。
    • a[mid] < a[high],即数组前半部分为循环递增数组,后半部分为严格递增数组时,若 key 大于 a[mid]并且不大于 a[high]时,则 key 落在数组后半部分;否则,key 落在数组前半部分。

这种方式的时间复杂度为:O(log(n)),空间复杂度为 O(1)。

代码如下:

package com.yyl.algorithm.questions;

public class BinarySearchDemo 
    public static void main(String[] args) 
        // 定义数组
        int[] a = 17, 19, 20, 21, 25, 1, 4,33, 7;
        // 调用改进后的二分查找法求索引 
        int pos = binarysearch(a, 7);
        System.out.println("要查找的元素的索引为:" + pos);
    

    /**
     * 改进后的二分查找法
     * @param a 查找的数组
     * @param e 要查找的元素
     * @return 下标
     */
    private static int binarysearch(int[] a, int e) 
        int low = 0;
        int high = a.length - 1;
        int mid = 0;
        // 数组下标 如果返回-1,表示查找失败
        int pos = -1;

        // 如果 low < high,说明循环查找结束,直接返回-1; 否则循环查找
        while (low <= high) 
            // mid 为中间值索引
            mid = (low + high) / 2;
            // 如果中间值刚好是 e,则查找成功,终止查找,e 的索引为 mid
            if (a[mid] == e) 
                pos = mid;
                break;
            
            // 如果 a[low] <= a[mid],说明原数组的前半部分是严格递增的,后半部分是一个更小的循环递增数组
            if (a[low] <= a[mid]) 
                // 如果要查找的元素 e 小于 a[mid]并且不小于 a[low]时, 则说明 e 落在数组前半部分
                if (a[low] <= e && e < a[mid]) 
                    high = mid - 1;
                 else
                    low = mid + 1;
                
             else     // 否则,后半部分是严格递增的,前半部分是一个更 小的循环递增数组
                // 如果要查找的元素 e 大于 a[mid]并且不大于 a[high]时, 则说明 e 落在数组后半部分
                if (a[mid] < e && e <= a[high]) 
                    low = mid + 1;
                 else     // 否则的话,需要在数组的前半部分继续查找
                    high = mid - 1;
                
            
        
        return pos;
    

请编写一个完整的程序,实现如下功能:从键盘输入数字 n,程序自动计算 n!并输出。(注 1:n!=1*2*3…*n, 注 2:请使用递归实现)

代码如下:

package com.yyl.algorithm.questions;

import java.util.Scanner;

public class FactorialDemo 
    public static void main(String[] args) 
        System.out.print("请输入一个整数:");
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(n + "的阶乘是:" + factorial(n));
    

    private static int factorial(int n) 
        if(n==1)
            return 1;
        
        return factorial(n-1)*n;
    


递归实现二分查询

**思路说明:**假设在一个已经排好序的有序序列(N 个元素,升序排列),首先让序列中的中间的元素与需要查找的关键字进行比较,如果相等,则查找成功,否则利用中间位置将序列分成两个子序列,如果待查找的关键字小于中间的元素,则在前一个子序列中同样的方法进一步查找,如果待查找的关键字大于中间的元素,则在后一个子序列中同样的方法进一步查找,重复以上过程一直到查找结束!

代码如下:

package com.yyl.algorithm.questions;

import java.util.Scanner;

public class BinarySearchRecursionDemo 
    public static void main(String[] args) 
        int[] a = 1, 3, 5, 7, 9, 11, 13;
        System.out.print("请输入要查找的元素:");
        int e = new Scanner(System.in).nextInt();
        int index = binarySearch(a, 0, a.length - 1, e);
        System.out.println(index != -1 ? "元素索引为" + index : " 没有该元素");
    

    private static int binarySearch(int[] a, int low, int high, int e) 
        int mid = 0;
        if (low <= high) 
            mid = (low + high) / 2;
            if (a[mid] == e) 
                return mid;
             else if (a[mid] > e) 
                return binarySearch(a, low, mid - 1, e);
             else 
                return binarySearch(a, mid + 1, high, e);
            
        
        // 如果大于就相当于判定递归的终止条件了
        return 以上是关于个人算法重刷记录的主要内容,如果未能解决你的问题,请参考以下文章

算法剑指 Offer 40. 最小的k个数 重刷

算法剑指 Offer 45. 把数组排成最小的数 重刷

算法剑指 Offer 38. 字符串的排列 重刷

算法剑指 Offer 42. 连续子数组的最大和 重刷

算法剑指 Offer 39. 数组中出现次数超过一半的数字 重刷

算法剑指 Offer 04. 二维数组中的查找 重刷