个人算法重刷记录

文章目录

对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符保证字符串中有重复的字符,字符串的长度小于等于 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");
        }
    }

}

image-20220919210046717

判断字符串是否是这样的组成的,第一个字母,后面可以是字母、数字、下划线、总长度为 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;
    }
}

image-20220919215930847

请编写一个完整的程序,实现如下功能:从键盘输入数字 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;
    }
}

image-20220919220205832

递归实现二分查询

**思路说明:**假设在一个已经排好序的有序序列(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 -1;
    }
}

image-20220919221129321

编写一段 Java 程序,把一句英语中的每个单词中的字母次序倒转,单词次序保持不变,例入输入为“There is a dog.”,输出结果应该是“erehT si a god.”要求不使用 Java 的库函数,例如 String 类的 split,reverse 方法

代码如下:

package com.yyl.algorithm.questions;

public class StringReverseDemo {
    
    
    public static void main(String[] args) {
    
    
        String input = "There is a dog";
        System.out.println("逆转后的字符串为:" + reverseWords(input));
    }

    private static String reverseWords(String input) {
    
    
        StringBuilder sb = new StringBuilder();
        // 将字符串转化成字符数组
        char[] arr = input.toCharArray();
        // index 用来记录每个单词的起始索引
        int index = 0;

        //遍历字符数组,将空格前边的单词挨个拼接到 str 中
        for (int i = 0; i < arr.length; i++) {
    
    
            if (arr[i] == ' ') {
    
    
                //根据空格的位置将空格前边一个单词密续追加到 str 中
                for (int j = i - 1; j >= index; j--) {
    
    
                    sb.append(arr[j]);
                }
                //单词拼接完成后,拼接一个空格
                sb.append(' ');
                //让 index 指向下一个单词的起始位置
                index = i + 1;
            }
        }

        //将最后一个单词拼接上
        for (int i = arr.length - 1; i >= index; i--) {
    
    
            sb.append(arr[i]);
        }

        return sb.toString();
    }
}

image-20220919225245614

手写 9x9 乘法表,冒泡排序

代码如下:

package com.yyl.algorithm.questions;

public class NineTable {
    
    
    public static void main(String[] args) {
    
    
        for (int x = 0; x <= 9; x++) {
    
    
            for (int y = 1; y <= x; y++) {
    
    
                System.out.print(y + "*" + x + "=" + x * y + "\t");
            }
            System.out.println();
        }
    }
}

image-20220919225449204

给定一个整数数组,找到是否该数组包含任何重复数字。你的函数应该返回 true 只要有任何数字 在该数组中重复出现,否则返回 false。

public class Solution {
    
    
    public boolean containsDuplicate(int[] nums) {
    
    
        Set<Integer> numSet = new HashSet<Integer>();
        for (int i = 0; i < nums.length; i++) {
    
    
            if (numSet.contains(nums[i])) 
                return true;
            else
                numSet.add(nums[i]);
        } 
        return false;
    }
}

给定一个数组 nums, 写一个函数来移动所有 0 元素到数组末尾,同时维持数组中非 0 元素的相对顺序不变。要求不能申请额外的内存空间,并且最小化操作次数。

package com.yyl.algorithm.questions;

import java.util.Arrays;

public class MoveZeroesDemo {
    
    
    public static void main(String[] args) {
    
    
        int[] nums = {
    
    1, 0, 5, 44, 0, 3, 7, 0, 88};
        moveZeroes(nums);
        System.out.println(Arrays.toString(nums));
    }

    public static void moveZeroes(int[] nums) {
    
    
        int size = nums.length;
        // 元素开始位置
        int startIndex = 0;
        // 元素结束位置
        int endIndex = 0;

        int currentNum;
        int i = 0;
        // 第一步:找到第一个 0 元素开始的位置
        while (i < size) {
    
    
            currentNum = nums[i];
            // 并将第一个 0 元素的游标赋值给 startIndex和endIndex
            if (currentNum == 0) {
    
    
                startIndex = i;
                endIndex = i;
                break;
            }
            ++i;
        }
        // 如果当前数组中没有找到 0 元素,则推出
        if (nums[endIndex] != 0) {
    
    
            return;
        }

        // 将当前 i 的值加 1;
        ++i;
        // 直接从刚才 0 元素位置的后一位置开始循环
        while (i < size) {
    
    
            currentNum = nums[i];
            //如果当前元素等于 0,则将 i 值赋值 给 endIndex
            if (currentNum == 0) {
    
    
                endIndex = i;
            } else {
    
    
                // 如果不为 0
                nums[startIndex] = currentNum;
                // 则将当前元素赋值给 nums[startIndex]
                nums[i] = 0;
                // 并将当前位置的元素赋值为 0
                ++startIndex;
                // startIndex 和 endIndex 都加 1;
                ++endIndex;
            }
            ++i;
        }
    }
}

运行结果:

image-20220920190847353

给定一颗二叉树,返回节点值得先序遍历,请使用迭代(非递归)方式实现。

package com.yyl.algorithm.questions;

import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class Solution {
    
    
    static class TreeNode {
    
    
        int val;
        TreeNode right;
        TreeNode left;

        public TreeNode(int val) {
    
    
            this.val = val;
        }
    }

    public static void main(String[] args) {
    
    
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);

        System.out.println(Arrays.toString(preorderTraversal(root).toArray()));
    }

    public static List<Integer> preorderTraversal(TreeNode root) {
    
    
        // 存放结果的列表
        List<Integer> result = new ArrayList<>();
        if (root == null){
    
    
            return result;
        }
        // 使用栈保存遍历的结点
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        // 遍历入栈的结点 将栈内结点 按照右 左入栈  这样取出才能取出左右
        while (!stack.isEmpty()){
    
    
            TreeNode node = stack.pop();
            result.add(node.val);
            if (node.right != null) {
    
    
                stack.push(root.right);
            }
            if (node.left != null) {
    
    
                stack.push(node.left);
            }
        }

        return result;
    }
}

运行结果:

image-20220920194835185

验证一棵树是否为有效的二叉搜索树 BST

package com.yyl.algorithm.questions;

import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class Solution {
    
    
    static class TreeNode {
    
    
        int data;
        TreeNode right;
        TreeNode left;

        public TreeNode(int val) {
    
    
            this.data = data;
        }
    }

    public static void main(String[] args) {
    
    
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);

        System.out.println(isValidBST(root));
    }

    private static int lastVisit = Integer.MIN_VALUE;


    public static boolean isValidBST(TreeNode root) {
    
    
        if (root == null) {
    
    
            return true;
        }
        // 先判断左子 树
        boolean judgeLeft = isValidBST(root.left);
        // 当前节点比上 次访问的数值要大
        if (root.data >= lastVisit && judgeLeft) {
    
    
            lastVisit = root.data;
        } else {
    
    
            return false;
        }
        // 后判断右子树
        boolean judgeRight = isValidBST(root.right);
        return judgeRight;
    }
}

运行结果:

image-20220920200454711


运行结果:


运行结果:

给定含有 n 个整数的数组 S,S 中是否存在三个元素 a,b,c 使得 a + b + c = 0? 找到所有这样的三元 组,并且结果集中不包含重复的三元组。

比如,

S = [-1, 0, 1, 2, -1, -4];

结果集为:

[ 
    [-1, 0, 1], 
    [-1, -1, 2] 
]

代码如下:

package com.yyl.algorithm.questions;

import javax.swing.tree.TreeNode;
import java.util.*;

public class Solution {
    
    
    public static void main(String[] args) {
    
    
        int[] S = {
    
    -1, 0, 1, 2, -1, -4, -3, -4, 4, 3};
        new Solution().get3Sum(S);
    }

    /**
     * 暴力
     *
     * @param S
     * @return
     */
    private Set<String> get3Sum(int[] S) {
    
    

        if (S.length < 3 || S == null) {
    
    
            return null;
        }

        //接收拼接的字符串
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < S.length; i++) {
    
    
            for (int j = 0; j < S.length; j++) {
    
    
                for (int z = 0; z < S.length; z++) {
    
    
                    //筛选出不是递减的一组元素
                    if (S[i] <= S[j] && S[j] <= S[z]) {
    
    
                        int sum = S[i] + S[j] + S[z];
                        if (sum == 0) {
    
    
                            String str = "(" + S[i] + "," + S[j] + "," + S[z] + ")";
                            sb.append(str + ";");
                        }
                    }
                }
            }
        }

        String s = sb.toString();
        s = s.substring(0, sb.length() - 1);
        String[] arr = s.split(";");
        Set<String> set = new HashSet<String>();

        //将所筛选出来的元素放入 Set 集合中,去重
        for (int k = 0; k < arr.length; k++) {
    
    
            set.add(arr[k]);
        }
        System.out.println(set);
        return set;
    }

    /**
     * 三指针法
     *
     * @param nums
     * @return
     */
    public List<List<Integer>> threeSum(int[] nums) {
    
    
        List<List<Integer>> result = new LinkedList<>();

        if (nums != null && nums.length > 2) {
    
    
            // 先对数组进行排序
            Arrays.sort(nums);
            // i 表示假设取第 i 个数作为结果
            for (int i = 0; i < nums.length - 2; ) {
    
    
                // 第二个数可能的起始位置
                int j = i + 1;
                // 第三个数可能是结束位置
                int k = nums.length - 1;
                while (j < k) {
    
    
                    // 如果找到满足条件的解
                    if (nums[j] + nums[k] == -nums[i]) {
    
    
                        // 将结果添加到结果含集中
                        List<Integer> list = new ArrayList<>(3);
                        list.add(nums[i]);
                        list.add(nums[j]);
                        list.add(nums[k]);
                        result.add(list);

                        // 第二个移动到下个位置  第三个往回移动 找到下一组解
                        // 因为这一组已经有解了 所以两个都要移动
                        k--;
                        j++;

                        // 从左向右找第一个与之前处理的数不同的数的下标
                        while (j < k && nums[j] == nums[j - 1]) {
    
    
                            j++;
                        }
                        // 从右向左找第一个与之前处理的数不同的数的下标
                        while (j < k && nums[k] == nums[k + 1]) {
    
    
                            k--;
                        }

                    }
                    // 和大于0
                    else if (nums[j] + nums[k] > -nums[i]) {
    
    
                        // 和大于0 说明大的数太大了
                        k--;
                        // 从右向左找第一个与之前处理的数不同的数的下标
                        while (j < k && nums[k] == nums[k + 1]) {
    
    
                            k--;
                        }
                    }
                    // 和小于 0
                    else {
    
    
                        j++;
                        // 从左向右找第一个与之前处理的数不同的数的下标
                        while (j < k && nums[j] == nums[j - 1]) {
    
    
                            j++;
                        }
                    }

                }

                // 指向下一个要处理的数
                i++;
                // 从左向右找第一个与之前处理的数不同的数的下标
                while (i < nums.length - 2 && nums[i] == nums[i - 1]) {
    
    
                    i++;
                }
            }
        }
        return null;
    }
}

子集问题

题目: 给定一个不包含相同元素的整数集合,nums,返回所有可能的子集集合。解答中集合不能包含重 复的子集。

比如, nums = [1, 2, 3], 一种解答为:

[
    [3],
    [1], 
    [2], 
    [1,2,3], 
    [1,3], 
    [2,3], 
    [1,2],
    []
] 

代码如下:

package com.yyl.algorithm.questions;

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

public class NoRepeatDemo {
    
    
    public static void main(String[] args) {
    
    
        int[] first = new int[]{
    
    1, 2, 3};
        ArrayList<ArrayList<Integer>> res = subsets(first);
        for (int i = 0; i < res.size(); i++) {
    
    
            System.out.println(res.get(i));
        }
    }

    private static ArrayList<ArrayList<Integer>> subsets(int[] nums) {
    
    
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        // 遍历到的当前项
        ArrayList<Integer> item = new ArrayList<Integer>();
        if (nums.length == 0 || nums == null) {
    
    
            return result;
        }
        // 排序
        Arrays.sort(nums);
        // 递归调用
        dfs(nums, 0, item, result);
        // 最后加上一个空集
        result.add(new ArrayList<Integer>()); 
        return result;
    }

    public static void dfs(int[] nums, int start, ArrayList<Integer> item, ArrayList<ArrayList<Integer>> result) {
    
    
        for (int i = start; i < nums.length; i++) {
    
    
            item.add(nums[i]);
            // item 是以整数为元素的动态数组,而 result 是以数组为元素的数 组,在这一步,当 item 增加完元素后,item 所有元素构成一个完整的子串, 再由 result 纳入
            result.add(new ArrayList<Integer>(item));
            // 从下一个位置开始遍历
            dfs(nums, i + 1, item, result);
            item.remove(item.size() - 1);
        }
    }
}

运行结果:

image-20220920213302895

编辑距离题目:给定两个单词 word1 和 word2,找到最小的操作步骤使得 word1 转换成 word2,每次操作算作一 步。你可以对单词进行以下三种操作:1)插入一个字符 2)删除一个字符 3)替换一个字符

算法分析:

也就是说,就是将一个字符串变成另外一个字符串所用的最少操作数,每次只能增加、删除或者替换一个字符。
首先我们令word1和word2分别为:michaelab和michaelxy(为了理解简单,我们假设word1和word2字符长度是一样的),dis[i][j]作为word1和word2之间的Edit Distance,我们要做的就是求出michaelx到michaely的最小steps。

首先解释下dis[i][j]:它是指word1[i]和word2[j]的Edit Distance。dis[0][0]表示word1和word2都为空的时候,此时他们的Edit Distance为0。很明显可以得出的,dis[0][j]就是word1为空,word2长度为j的情况,此时他们的Edit Distance为j,也就是从空,添加j个字符转换成word2的最小Edit Distance为j;同理dis[i][0]就是,word1长度为i,word2为空时,word1需要删除i个字符才能转换成空,所以转换成word2的最小Edit Distance为i。

下面及时初始化代码:

for (int i = 0; i < row; i++) dis[i][0] = i;
for (int j = 0; j < col; j++) dis[0][j] = j;
下面来分析下题目规定的三个操作:添加,删除,替换。
假设word1[i]和word2[j](此处i = j)分别为:michaelab和michaelxy
显然如果b==y, 那么dis[i][j] = dis[i-1][j-1]。
如果b!=y,那么:
添加:也就是在michaelab后面添加一个y,那么word1就变成了michaelaby,此时
dis[i][j] = 1 + dis[i][j-1];

上式中,1代表刚刚的添加操作,添加操作后,word1变成michaelaby,word2为michaelxy。dis[i][j-1]代表从word[i]转换成word[j-1]的最小Edit Distance,也就是michaelab转换成michaelx的最小Edit Distance,由于两个字符串尾部的y==y,所以只需要将michaelab变成michaelx就可以了,而他们之间的最小Edit Distance就是dis[i][j-1]。

运行结果:


运行结果:

买卖股票问题:题目: 你有一个数组,第 i 个元素表示第 i 天某个股票的价格,设计一个算法找到最大的利润,并且你只能最多完成两次交易。

解题思路:

比如给定一组数组,[1,2,3,6,9,3,10]

最可以 2 次去获取最大的利益,可以用 2 分的思想,分成 2 部分,

从 0 元素开始遍历分别求出左右 2 边的最大利益,求出的左右 2 边最大的利益即为解

public class Solution {
    
    
    public int maxProfit(int prices[]) {
    
    
        int n = prices.length;
        // 第一次买
        int buy1 = prices[0], sell1 = 0;
        // 第二次买
        int buy2 = prices[0], sell2 = 0;
        for (int i = 1; i < n; ++i) {
    
    
            buy1 = Math.min(buy1, prices[i]);
            sell1 = Math.max(sell1, prices[i] - buy1);
            buy2 = Math.min(buy2, prices[i] - sell1);
            sell2 = Math.max(sell2, prices[i] - buy2);
        }
        return sell2;
    }
}

第二种方法:

package com.yyl.algorithm.questions;

public class Solution {
    
    
    public static int maxProfit(int[] prices) {
    
    
        if (null == prices || 0 == prices.length) {
    
    
            return 0;
        }
        int sumProfit = 0;
        for (int i = 1; i < prices.length; i++) {
    
    
            int tmpsum = maxProfit(prices, 0, i) + maxProfit(prices, i + 1, prices.length - 1);
            sumProfit = Math.max(sumProfit, tmpsum);
        }
        return sumProfit;
    }

    public static int maxProfit(int[] prices, int s, int e) {
    
    
        if (e <= s) {
    
    
            return 0;
        }
        int min = prices[s];
        int maxProfit = 0;
        for (int i = s + 1; i <= e; i++) {
    
    
            maxProfit = Math.max(maxProfit, prices[i] - min);
            min = Math.min(min, prices[i]);
        }
        return maxProfit;

    }

    public static void main(String[] args) {
    
    
        int arr[] = {
    
    4, 4, 6, 1, 1, 4, 2, 5};
        System.out.println(maxProfit(arr));
    }
}

运行结果:

image-20220921095936497

任给 n 个整数和一个整数 x。请计算 n 个整数中有多少对整数之和等于 x。

package com.yyl.algorithm.questions;

import java.util.Arrays;
import java.util.Scanner;

public class NumsSumToX {
    
    
    public static void main(String[] args) {
    
    
        // 输入 n 个整数和一个整数
        Scanner input = new Scanner(System.in);
        System.out.println("请输入 n 个整数,数量任意,以逗号分隔 ");
        String str = input.next();
        System.out.println("请输入一个整数:");
        int x = input.nextInt();

        // 将 n 个整数的字符串转换为数组
        String[] arr1 = str.split(",");

        int[] arr2 = new int[arr1.length];
        for (int i = 0; i < arr1.length; i++) {
    
    
            arr2[i] = Integer.parseInt(arr1[i]);
        }
        System.out.println(Arrays.toString(arr2));

        // 判断并输出 n 个整数中有几对的和等于 x
        int count = 0;
        for (int i = 0; i < arr2.length - 1; i++) {
    
    
            for (int j = i + 1; j < arr2.length; j++) {
    
    
                if (arr2[i] + arr2[j] == x) {
    
    
                    count++;
                }
            }
        }
        System.out.println(count);
    }
}

运行结果:

请说明快速排序算法的设计思想和时间复杂度,并用高级语言写出对整数数组进行一趟快排的函数实现。

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列的一个效果,这样的排序叫做快速排序

设要排序的数组是 A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序

值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

一趟快速排序的算法是:

1、设置两个变量 i、j,排序开始的时候:i=0,j=N-1;

2、以第一个数组元素作为关键数据,赋值给 key,即 key=A[0];

3、从 j 开始向前搜索,即由后开始向前搜索(j–),找到第一个小于 key 的值 A[j],将 A[j]和 A[i]互换;

4、从 i 开始向后搜索,即由前开始向后搜索(i++),找到第一个大于 key 的 A[i],将 A[i]和 A[j]互换;

5、重复第 3、4 步,直到 i=j; (3,4 步中,没找到符合条件的值,即 3 中 A[j]不小于 key,4 中 A[i]不大于 key 的时候改变 j、i 的值,使得 j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候 i, j 指针位置不变。另外,i==j 这一过程一定正好是 i+或 j-完成的时候,此时令循环结束)。

1、设置两个变量i、j,排序开始的时候:i=0,j=N-1

2、以第一个数组元素作为关键数据,赋值给key,即key=A[0]

3、从j开始向前搜索,即由后向前搜索(j–),找到第一个小于key的值A[i]

4、从i开始向后搜索,即由前向后搜索(i++),找到第一个大于key的值A[j]

5、将 A[j]和 A[i]互换

6、重复上面的3、4、5步,知道 i==j

如果第3、4、5步,没找到符合条件的值,即3中的 A[j]不小于key,4 中 A[i]不大于 key 的时候,改变 j、i 的值,使得 j=j-1,i=i+1,直至找到为止。

找到符合条件的值,进行交换的时候 i, j 指针位置不变。

另外,i==j 这一过程一定正好是 i++ 或 j-- 完成的时候,此时令循环结束

package com.yyl.algorithm.questions;

import java.util.Arrays;

public class QuickSortDemo {
    
    
    public static void main(String[] args) {
    
    
        int arr[] = {
    
    90, 60, 70, 50, 40, 80, 20, 100, 10};
        quicksort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    /**
     * 快速排序
     * @param arr 排序数组
     * @param left 左起点
     * @param right 右起点
     */
    private static void quicksort(int[] arr, int left, int right) {
    
    
        if (left>right){
    
    
            return;
        }
        int i=left;
        int 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);
        }
        swap(arr,left,i);
        quicksort(arr,left,i-1);
        quicksort(arr,i+1,right);
    }

    private static void swap(int[] arr,int i,int j){
    
    
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
}

运行结果:

image-20220921103653922

对于一段形如:1,-13,115×3 的输入

输入会依照以下规则:

1、所有输入为整数、

2、“,”为分隔符

3、“”表示一个区间,比如“-13”表示-1 到 3 总共 5 个整数,同时“”前的数小于“”后的数:

4、“x”表示步长,“x3”指每 3 个整数一个,比如“1~15×3”表示 1,4,7,10,13;

根据以上得到的结果进行打印,打印的规则为:

1、所有得到的整数按从小到大排列,以“,”分隔,不计重复;

2、每行最多显示 3 个整数;

3、如果两个整数是连续的,可以放在同一行,否则自动换行。

例如对于输入“1,-13,115×3”的输出结果为:

-1,0,1,
2,3,4,
7,
10,
13

代码如下:

package com.yyl.algorithm.questions;

import java.util.*;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Map<Integer, Integer> map = new TreeMap<Integer, Integer>();
        String str = "5~20x3,1,-1~3,1~15x3";
        String[] s = str.split(",");

        for (int i = 0; i < s.length; i++) {
    
    
            if (s[i].contains("~")) {
    
    
                String ss[] = s[i].split("~");
                int first = Integer.parseInt(ss[0]);
                if (s[i].contains("x")) {
    
    
                    String sss[] = ss[1].split("x");
                    int end = Integer.parseInt(sss[0]);
                    int l = Integer.parseInt(sss[1]);
                    for (int j = first; j < end; ) {
    
    
                        map.put(j, j);
                        j += l;
                    }
                } else {
    
    
                    int end = Integer.parseInt(ss[ss.length - 1]);
                    for (int j = first; j <= end; j++) {
    
    
                        map.put(j, j);
                    }
                }
            } else {
    
    
                int j = Integer.parseInt(s[i]);
                map.put(j, j);
            }
        }
        List<Integer> list = new ArrayList<Integer>();
        Set<Integer> set = map.keySet();
        Iterator<Integer> ite = set.iterator();
        while (ite.hasNext()) {
    
    
            int key = ite.next();
            int value = map.get(key);
            list.add(value);
            System.out.println("v :" + value);
        }
        System.out.println("=================");
        for (int i = 0; i < list.size(); ) {
    
    
            int value = list.get(i);
            List<Integer> co = new ArrayList<Integer>();
            co.add(value + 1);
            co.add(value + 2);
            if (list.containsAll(co)) {
    
    
                System.out.println(value + "," + (value + 1) + "," + (value + 2));
                i += 3;
            } else {
    
    
                System.out.println(value);
                i++;
            }
        }
    }
}

运行结果:

image-20220921105907681

有两个字符串:目标串 S=“s1s2…sn”,模式串 T=“t1t2…tm”。 若存在 T 的每个字符一次和 S 中的一个连续字符序列相等,则匹配成功,返 回 T 中第一个字符在 S 中的位置。否则匹配不成功,返回 0。写出你的算法, 要求线性时间复杂度

答:

字符串匹配操作定义:

目标串 S=“S0S1S2…Sn-1” , 模式串 T=“T0T1T2…Tm-1”

对合法位置 0<= i <= n-m (i 称为位移)依次将目标串的字串 S[i … i+m-1] 和

模式串 T[0 … m-1] 进行比较,若:

1、S[i … i+m-1] = T[0 … m-1] , 则从位置 i 开始匹配成功,称模式串 T 在目标 串 S 中出现。

2、S[i … i+m-1] != T[0 … m-1] ,则从位置 i 开始匹配失败。

字符串匹配算法 —— Brute-Force 算法字符串匹配过程中,对于位移 i (i 在目标串中的某个位置),当第一次 Sk != Tj 时, i 向后移动 1 位 ,及 i = i+1,此时 k 退回到 i+1 位置 ;模式串要退回到第一个字符。

该算法时间复杂度 O(M*N),但是实际情况中时间复杂度接近于 O(M + N),以下为 Brute-Force 算法的 Java 实现版本:

package com.yyl.algorithm.questions;

import java.util.Arrays;

public class StringMatchDemo {
    
    
    public static void main(String[] args) {
    
    
        String s = "ababcabdabcabca";
        String t = "abcabc";
        StringMatchDemo bruteforce = new StringMatchDemo();
        int index = getIndex(s, t);
        System.out.println("Brutesy算法:对应相同字符在原字符串的第" + index + "位开始到" + (index + t.length() - 1) + "位");

        String str1 = "BBC ABCDAB ABCDABCDABDE";
        String str2 = "ABCDABD";

        int index2 = strStr(str1, str2);
        System.out.println("KMP算法:对应相同字符在原字符串的第" + index2 + "位开始到" + (index2 + str2.length() - 1) + "位");
    }

    /**
     * Brutesy算法
     *
     * @param s
     * @param t
     * @return
     */
    public static int getIndex(String s, String t) {
    
    
        //主串比模式串长时开始比较
        if (s != null && t != null && t.length() > 0 && s.length() >= t.length()) {
    
    
            int sLen = s.length(), tLen = t.length();
            // i j 分别是原字符串 与 目标串下标
            int i = 0, j = 0;
            while ((i < sLen) && (j < tLen)) {
    
    
                if (s.charAt(i) == t.charAt(j)) {
    
    
                    i++;
                    j++;              //当主串字符与模式串字符相同时,查找成功,主串和模式串同时往后开始遍历匹配
                } else {
    
    
                    i = i - j + 1;
                    j = 0;          //主串字符与模式串字符不相同时,查找失败,i 返回到原来位置加 1 ,j 返回到0
                }
            }
            if (j >= t.length()) {
    
        // 匹配成功,返回子串的序号
                return i - tLen;
            } else {
    
                      // 匹配失败,返回-1
                return -1;
            }
        }
        return -1;
    }

    /**
     * KMP算法
     *
     * @param source
     * @param target
     * @return
     */
    public static int strStr(String source, String target) {
    
    
        if (target.length() == 0) {
    
    
            return 0;
        }
        // 记录前缀
        int[] next = new int[target.length()];
        getNext(next, target);
        System.out.println(Arrays.toString(next));

        // i 原字符串遍历的下标  j 目标字符串遍历的下标
        for (int i = 0, j = 0; i < source.length(); i++) {
    
    
            // 如果不相等就要一直等于前缀
            /*
            因为j表示当前遍历到的目标串的下标,都不一样了,按照常理是j=0直接从头查,但是可能有重复前缀
            那么只能移动到上一个元素的前缀里了就OK了

            比到这样的时候
            BBC ABCDAB ABCDABCDABDE
                ABCDABD
                0000122
            不用到下一个再比一下,直接看D的上一个还一样的值的前缀,前缀是2
            BBC ABCDAB ABCDABCDABDE
                    ABCDABD
                    0000122
            那么j再比的时候就直接从 2开始比  也就是比C和空格
            此时 i 就是空格的位置
            还是在  while (j > 0 && source.charAt(i) != target.charAt(j)) 此时发现还是不同
            j就等于前缀0了  j不大于0了 跳出while,然后i++,再继续比        
             */
            while (j > 0 && source.charAt(i) != target.charAt(j)) {
    
    
                j = next[j - 1];
            }
            if (source.charAt(i) == target.charAt(j)) {
    
    
                j++;
            }
            if (j == target.length()) {
    
    
                return i - j + 1;
            }
        }
        return -1;
    }

    private static void getNext(int[] next, String target) {
    
    
        int len = target.length();
        next[0] = 0;
        //ABCDABD
        for (int i = 1, j = 0; i < len; i++) {
    
    
            while (j > 0 && target.charAt(i) != target.charAt(j)) {
    
    
                // 如果不同  当前的包含元素的前缀就和前一个一样
                j = next[j - 1];
            }
            if (target.charAt(i) == target.charAt(j)) {
    
    
                j++;
            }
            next[i] = j;
        }
    }
}

运行结果:

image-20220921190534003


运行结果:

如何生成一个 0-100 的随机整数

package com.yyl.algorithm.questions;

import java.util.*;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        int num = (int) (Math.random() * 101);
        System.out.println(num);
    }
}

运行结果:

image-20220921190642622

请编写一段 Java 程序将两个有序数组合并成一个有序数组

package com.yyl.algorithm.questions;

import java.util.*;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        int[] a = {
    
    1, 2, 3, 4, 5, 7, 8, 9, 10};
        int[] b = {
    
    3, 5, 7, 9, 10};
        int[] target = new int[a.length + b.length];
        for (int i = 0; i < a.length; i++) {
    
    
            target[i] = a[i];
        }
        for (int j = 0; j < b.length; j++) {
    
    
            target[a.length + j] = b[j];
        }
        Arrays.sort(target);
        for (int i = 0; i < target.length; i++){
    
    
            System.out.println(target[i]);
        }
    }
}

统计一篇英文文章单词个数

package com.yyl.algorithm.questions;

import java.io.FileReader;

public class WordCounting {
    
    
    public static void main(String[] args) {
    
    
        try (FileReader fr = new FileReader("resource/a.txt")) {
    
    
            int counter = 0;
            boolean state = false;
            int currentChar;
            while ((currentChar = fr.read()) != -1) {
    
    
                if (currentChar == ' ' || currentChar == '\n' || currentChar == '\t' || currentChar == '\r') {
    
    
                    state = false;
                } else if (!state) {
    
    
                    state = true;
                    counter++;
                }
            }
            System.out.println(counter);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}


运行结果:

image-20220921192752081

输入年月日,计算该日期是这一年的第几天

package com.yyl.algorithm.questions;

import java.util.Scanner;

public class DayCounting {
    
    
    public static void main(String[] args) {
    
    
        // 平年和闰年月份的天数
        int[][] data = {
    
    
                {
    
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                {
    
    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
        };
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入年月日(1980 11 28): ");
        int year = sc.nextInt();
        int month = sc.nextInt();
        int date = sc.nextInt();
        int[] daysOfMonth = data[(year % 4 == 0 && year % 100 != 0 || year % 400 == 0) ? 1 : 0];
        int sum = 0;
        for (int i = 0; i < month - 1; i++) {
    
    
            sum += daysOfMonth[i];
        }
        sum += date;
        System.out.println(sum);
        sc.close();
    }
}

运行结果:

image-20220921193128813

回文素数:所谓回文数就是顺着读和倒着读一样的数(例如:11,121,1991…),回文素数就是既是回文数又是素数(只能被 1 和自身整除的数)的数。编程找出 11~9999 之间的回文素数。

package com.yyl.algorithm.questions;

public class PalindromicPrimeNumber {
    
    
    public static void main(String[] args) {
    
    
        for (int i = 11; i <= 9999; i++) {
    
    
            if (isPrime(i) && isPalindromic(i)) {
    
    
                System.out.println(i);
            }
        }
    }

    /**
     * 是否为素数
     *
     * @param n
     * @return
     */
    private static boolean isPrime(int n) {
    
    
        for (int i=2;i<Math.sqrt(n);i++){
    
    
            if (n%i==0){
    
    
                return false;
            }
        }
        return true;
    }

    /**
     * 是否为回文
     *
     * @param n
     * @return
     */
    private static boolean isPalindromic(int n) {
    
    
        int temp = n;
        int sum = 0;
        while(temp > 0) {
    
    
            sum= sum * 10 + temp % 10;
            temp/= 10;
        }
        return sum==n;
    }
}

运行结果:

image-20220921193654708

全排列:给出五个数字 12345 的所有排列。

package com.yyl.algorithm.questions;

public class FullPermutation {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    1, 2, 3, 4, 5};
        perm(arr, 0);
    }

    /**
     * 递归全排列
     * @param arr
     * @param k
     */
    private static void perm(int[] arr, int k) {
    
    
        if (k == arr.length) {
    
    
            // 打印当前遍历的结果
            for (int i = 0; i < arr.length; i++) {
    
    
                System.out.print(arr[i]);
            }
            System.out.println();
            return;
        }
        for (int i = k; i < arr.length; i++) {
    
    
            swap(arr, k, i);
            perm(arr, k + 1);
            swap(arr, k, i);
        }
    }

    private static void swap(int[] arr, int i, int j) {
    
    
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

运行结果:

image-20220921195200487

DFS全排列:

class Solution {
    
    
    private List<List<Integer>> result;
    private ArrayList<Integer> tmp;

    public List<List<Integer>> permute(int[] nums) {
    
    
        result = new ArrayList<>();
        tmp = new ArrayList<Integer>();
        // 节点访问标志
        int[] visited = new int[nums.length];
        dfs(nums, visited);
        return result;
    }

    // DFS
    private void dfs(int[] nums,  int[] visited) {
    
    
        // 如果递归到 规定长度了,把当前遍历的序列加到结果集
        if (tmp.size() == nums.length) {
    
    
            result.add(new ArrayList<>(tmp));
            return;
        }
        // 一层层的遍历  加完当前在退回去
        for (int i = 0; i < nums.length; i++) {
    
    
            // 针对于当前tmp如果访问过当前的了  就继续下一个
            if (visited[i] == 1){
    
    
                continue;
            }
            // 当前访问 加入tmp
            visited[i] = 1;
            tmp.add(nums[i]);
            // 继续 DFS
            dfs(nums, visited);
            // 退回当前访问 移出tmp
            visited[i] = 0;
            tmp.remove(tmp.size() - 1);
        }
    }
}

对于一个有 N 个整数元素的一维数组,找出它的子数组(数组中下标连续的元素组成的数组)之和的最大值。

答:下面给出几个例子(最大子数组用粗体表示):

  1. 数组:{ 1, -2, 3,5, -3, 2 },结果是:8

  2. 数组:{ 0, -2, 3, 5, -1, 2 },结果是:9

  3. 数组:{ -9, -2,-3, -5, -3 },结果是:-2


运行结果:

用递归实现字符串倒转

private static String reverseReturnWords(String input) {
    
    
    if (input == null || input.length() == 1) {
    
    
        return input;
    }
    return reverseReturnWords(input.substring(1)) + input.charAt(0);
}

输入一个正整数,将其分解为素数的乘积

package com.yyl.algorithm.questions;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class DecomposeInteger {
    
    

    private static List<Integer> list = new ArrayList<Integer>();

    public static void main(String[] args) {
    
    
        System.out.print("请输入一个数: ");
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        decomposeNumber(n);
        list.stream().forEach(integer -> System.out.println(integer));
    }

    private static void decomposeNumber(int n) {
    
    
        // 如果本身就素数
        if (isPrime(n)) {
    
    
            list.add(n);
            list.add(1);
        } else {
    
    
            // 从最大的素数开始找
            doIt(n, (int) Math.sqrt(n));
        }
    }

    public static void doIt(int n, int div) {
    
    
        if (isPrime(div) && n % div == 0) {
    
    
            list.add(div);
            decomposeNumber(n / div);
        } else {
    
    
            doIt(n, div - 1);
        }
    }

    private static boolean isPrime(int n) {
    
    
        for (int i = 2; i <= Math.sqrt(n); i++) {
    
    
            if (n % i == 0) {
    
    
                return false;
            }
        }
        return true;
    }
}

运行结果:

image-20220921204043474

一个有 n 级的台阶,一次可以走 1 级、2 级或 3 级,问走完 n 级台阶有多少种走法。

package com.yyl.algorithm.questions;

public class GoStepsDemo {
    
    
    public static int countWays(int n) {
    
    
        if (n < 0) {
    
    
            return 0;
        } else if (n == 0) {
    
    
            return 1;
        } else {
    
    
            return countWays(n - 1) + countWays(n - 2) + countWays(n - 3);
        }
    }

    public static void main(String[] args) {
    
    
        System.out.println(countWays(5)); // 13 }
    }
}

运行结果:

image-20220921204213272

写一个算法判断一个英文单词的所有字母是否全都不同(不区分大小写)

package com.yyl.algorithm.questions;

public class AllNotTheSameDemo {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(judge("hello"));
        System.out.print(judge("smile"));
    }

    public static boolean judge(String str) {
    
    
        String temp = str.toLowerCase();
        int[] letterCounter = new int[26];
        for (int i = 0; i < temp.length(); i++) {
    
    
            int index = temp.charAt(i) - 'a';
            letterCounter[index]++;
            if (letterCounter[index] > 1) {
    
    
                return false;
            }
        }
        return true;
    }
}

运行结果:

image-20220921204328492

有一个已经排好序的整数数组,其中存在重复元素,请将重复元素删除掉,例如,A= [1, 1, 2, 2, 3],处理之后的数组应当为 A= [1, 2, 3]。

package com.yyl.algorithm.questions;

import java.util.Arrays;

public class RemoveDuplication {
    
    
    public static int[] removeDuplicates(int a[]) {
    
    
        if (a.length <= 1) {
    
    
            return a;
        }
        int index = 0;
        for (int i = 1; i < a.length; i++) {
    
    
            if (a[index] != a[i]) {
    
    
                a[++index] = a[i];
            }
        }
        int[] b = new int[index + 1];
        System.arraycopy(a, 0, b, 0, b.length);
        return b;
    }

    public static void main(String[] args) {
    
    
        int[] a = {
    
    1, 1, 2, 2, 3};
        a = removeDuplicates(a);
        System.out.println(Arrays.toString(a));
    }
}

运行结果:

image-20220921205630058

给一个数组,其中有一个重复元素占半数以上,找出这个元素

package com.yyl.algorithm.questions;

public class FindMost {
    
    
    public static void main(String[] args) {
    
    
        String[] strs = {
    
    "kiss","hello", "kiss", "hello", "hello", "maybe"};
        System.out.println(find(strs));
    }

    public static <T> T find(T[] x) {
    
    
        T temp = null;
        for (int i = 0, nTimes = 0; i < x.length; i++) {
    
    
            if (nTimes == 0) {
    
    
                temp = x[i];
                nTimes = 1;
            } else {
    
    
                if (x[i].equals(temp)) {
    
    
                    nTimes++;
                } else {
    
    
                    nTimes--;
                }
            }
        }
        return temp;
    }
}

运行结果:

image-20220921210321490

编写一个方法求一个字符串的字节长度?

package com.yyl.algorithm.questions;

import java.util.*;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        String str="dhdasd j中的法不是你";
        System.out.println(getWordCount(str));
    }

    public static int getWordCount(String s) {
    
    
        int length = 0;
        for (int i = 0; i < s.length(); i++) {
    
    
            int ascii = Character.codePointAt(s, i);
            if (ascii >= 0 && ascii <= 255) {
    
    
                length++;
            }
            else{
    
    
                length += 2;
            }
        }
        return length;
    }
}

运行结果:

image-20220921210514412

猜你喜欢

转载自blog.csdn.net/weixin_45525272/article/details/126980915