Algorithm Practice Record【2】

「动态规划一背包重量装满体积不限」

题目描述
昨天是三八妇女节,在尧山食堂中央举办了一个活动所有的女童鞋可以再此免费拿走自己想要的物品。由于时间紧迫,Mary决定要将自己的背包装满。由于物品较多,且每个物品都有自己的重量,而Mary的背包只能承受固定的重量,她很烦恼如何才能装满自己的包包,所以现在交给你来将Mary的背包装满吧。
注意:每种物品只能选一次,不考虑包的空间大小。
输入
第一行包含两个空格分开的整数N(1≤ N ≤ 100)和S(1≤ S ≤ 1000)现场有N个物品和Mary的背包最多只能装S千克的物品;
第二行是N个正整数Wi(0 < Wi ≤ 100),表示每个物品的重量(单位千克)。
输出
若能将Mary的背包重量装满则输出“YES”,否则输出“NO”。
输入样例 1
7 15
1 4 3 4 5 2 7
输出样例 1
YES

输入样例 2
4 38
20 24 24 44
输出样例 2
NO

输入样例 3
9 81
8 37 29 19 35 49 9 34 8
输出样例 3
YES

代码案例解析

import java.util.Scanner;

public class 动态规划一背包装满体积不限 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int size = in.nextInt();
        int weight = in.nextInt();
        int[] goods = new int[size];
        for (int i = 0; i < size; i++) {
            goods[i] = in.nextInt();
        }
        boolean[][] dp = new boolean[size+1][weight+1];

        int sum = 0;
        for (int i = 0; i < size; i++) {
            sum += goods[i];
        }
        // 总重装不满背包则false
        if (sum<weight){
            System.out.println("NO");
            return;
        }
        // 目标重量为0时,必定true
        for (int i = 0; i <= size; i++) {
            dp[i][0] = true;
        }
        // 可放物品为0时,必定false
        for (int i = 1; i <= weight; i++) {
            dp[0][i] = false;
        }
        for (int i = 1; i <= size; i++) {
            for (int j = 1; j <= weight; j++) {
                if (goods[i-1] > j){ // 如果第i个物品重量>j则不能放,且结果为上一个物品放j的结果
                    dp[i][j] = dp[i-1][j];
                }else if (goods[i-1] == j){ // 如果第i个物品重量=j,则一定可以装满
                    dp[i][j] = true;
                } else { // 如果第i个物品<j,则,可以装,也可以不装。不装:结果为上一个物品i-1装j;装:结果为上一个物品i-1装j-goods的重量
                    dp[i][j] = dp[i-1][j] || dp[i-1][j-goods[i-1]];
                }
            }
        }
        System.out.println(dp[size][weight]?"YES":"NO");
    }
}

「动态规划一字符串转换最小操作次数」

问题描述
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
插入一个字符
删除一个字符
替换一个字符
示例 :
输入: word1 = “horse”, word2 = “ros”
输出: 3
解释
horse -> rorse (将 ‘h’ 替换为 ‘r’)
rorse -> rose (删除 ‘r’)
rose -> ros (删除 ‘e’)

代码案例解析

import java.util.Scanner;

public class 动态规划一字符串转换最小操作次数 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String line1 = in.nextLine();
        String line2 = in.nextLine();
        String[] arrRow = line1.split("");
        String[] arrClo = line2.split("");
        int[][] dp = new int[arrRow.length+1][arrClo.length+1];
        // 当行和列为0时,表示有一个为空字符串,则只能进行添加和删除操作,则[][]固定+1
        for (int i = 0; i <= arrRow.length; i++) {
            dp[i][0] = i;
        }
        for (int i = 0; i <= arrClo.length; i++) {
            dp[0][i] = i;
        }
        for (int i = 1; i <= arrRow.length; i++) {
            for (int j = 1; j <= arrClo.length; j++) {
                if (arrRow[i-1].equals(arrClo[j-1])){
                    dp[i][j] = dp[i-1][j-1];
                }else {
                    dp[i][j] = Math.min(Math.min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
                }
            }
        }
        System.out.println(dp[arrRow.length][arrClo.length]);
    }
}

「N以内的素数个数」

题目描述
编写一个程序,读取整数 n 并打印小于或等于 n 的素数的个数。素数是一个自然数,它恰好有两个不同的自然数约数:1 和它本身。例如,前四个素数是:2、3、5、7。
输入
输入一行中只有一个整数 n (0<n<100000001)
输出
打印素数的个数
样例
输入样例
6
输出样例
3

代码案例解析

import java.util.Scanner;

public class n以内的素数个数 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        int size = 0;
        boolean [] nums = new boolean[num+1]; // 利用默认false代表没有因数(即为质数)
        for (int i = 2; i <= num; i++) {
            if (nums[i]==false){ // 2是质数,则将所有倍数置为true,表示有因数(即非质数)
                size ++;
                for (int j = 2; j*i <= num; j++) {
                    nums[j*i] = true;
                }
            }
        }
        System.out.println(size);
    }
}

「元音字母大写」

题目描述
元音字母(a,e,i,o,u,A,E,I,O,U),吧字符串中元音字母写成大写的,辅音字母则都写成小写
输入
输入一个字符串S(长度不超过100,只包含大小写的英文字母和空格)。
输出
按照要求输出翻译后的字符串S。
样例
输入样例
Who Love Solo
输出样例
whO lOvE sOlO

代码案例解析

import java.util.Locale;
import java.util.Scanner;

public class 元音字母大写 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println(in.nextLine().toLowerCase(Locale.ROOT).replaceAll("a","A")
                .replaceAll("e","E").replaceAll("i","I")
                .replaceAll("o","O").replaceAll("u","U"));
    }
}

「全排列A一递归」

题目描述
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
比如输入3,则排列1,2,3
123
132
213
231
312
321
代码案例解析

import java.util.Scanner;

public class 全排列A一递归 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int line = in.nextInt();
        int[] lineArrays = new int[line];
        for (int i = 1; i <= line; i++) {
            lineArrays[i-1] = i;
        }
        digui(0,lineArrays);
    }
    static void digui(int index,int[] lineArrays){
        if (index == lineArrays.length){ // 固定到末尾,则本次排列结束,打印
            printArrays(lineArrays);
        }
        for (int i = index; i < lineArrays.length; i++) { // index表示替换第几位,i表示从第几位数往后比较每一位
            // 交换第index位和第i位(i一定从index开始,到最后)
            swap(index,i,lineArrays);
            // 交换目标位,递归比较后面位数
            digui(index+1,lineArrays);
            // 还原上面的交换
            swap(index,i,lineArrays);
        }
    }

    static void swap(int index,int i,int[] lineArrays){
        int temp = lineArrays[index];
        lineArrays[index] = lineArrays[i];
        lineArrays[i] = temp;
    }

    static void printArrays(int[] lineArrays){
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < lineArrays.length; i++) {
            sb.append(lineArrays[i]+" ");
        }
        System.out.println(sb.toString().trim());
    }
}

「全排列B一字符串contains不重复」

题目描述
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
比如输入3,则排列1,2,3
123
132
213
231
312
321
代码案例解析

import java.util.Scanner;
public class 全排列B一字符串contains不重复 {
    static int m;
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        m = s.nextInt();
        combination(0, "");
    }
    private static void combination(int index, String str) {
        if (index == m) {
            System.out.println(str.trim());
            return;
        } else {
            for (int i = 1; i <= m; i++) {
                if (str.contains(String.valueOf(i))) {
                    continue;
                }
                combination(index + 1, str + i + " ");
            }
        }
    }
}

「全排列字符串去重一递归」

题目描述
给定一个只包含大写英文字母的字符串S,要求你给出对S重新排列的所有不相同的排列数。
如:S为ABA,则不同的排列有ABA、AAB、BAA三种。
输入
输入一个长度不超过10的字符串S,我们确保都是大写的。
输出
输出S重新排列的所有不相同的排列数(包含自己本身)。
样例
输入样例 1:ABA
输出样例 1:3

输入样例 2:ABCDEFGHHA
输出样例 2:907200

输入样例 3:AABBCC
输出样例 3:90

代码案例解析

import java.util.Scanner;

public class 全排列字符串去重 {
    static int count = 0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String line = in.nextLine();
        String[] lineArrays = line.split("");
        digui(0,lineArrays);
        System.out.println(count);
    }
    static void digui(int index,String[] lineArrays){
        if (index == lineArrays.length){ // 固定到末尾,则本次排列结束,打印
            count++;
        }

        for (int i = index; i < lineArrays.length; i++) { // index表示替换第几位,i表示从第几位数往后比较每一位
            boolean flag = false;
            for (int j = index; j < i; j++) { // 与之前的每一位比较,如果重复则跳过替换
                if (lineArrays[j].equals(lineArrays[i])){
                    flag = true;
                    break;
                }
            }
            if (flag){
                continue;
            }
            // 交换第index位和第i位(i一定从index开始,到最后)
            swap(index,i,lineArrays);
            // 交换目标位,递归比较后面位数
            digui(index+1,lineArrays);
            // 还原上面的交换
            swap(index,i,lineArrays);
        }
    }

    static void swap(int index,int i,String[] lineArrays){
        String temp = lineArrays[index];
        lineArrays[index] = lineArrays[i];
        lineArrays[i] = temp;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值