第十四届蓝桥杯集训——练习解题阶段(无序阶段)-Java全排列公式

简介: 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-Java全排列公式

第十四届蓝桥杯集训——练习解题阶段(无序阶段)-Java全排列公式


前言

       最近的一些文章都可能会很碎,写到哪里是哪里,过一阵子会具体的整理一遍,这里其它的类型题先往后排一排,因为蓝桥最后考的也就是对题目逻辑的理解能力,也就是dp分析能力了,所以就主要目标定在这里,最近的题目会很散,很多,基本上都是网罗全网的一些dp练习题进行二次训练,准备比赛的学生底子薄的先不建议看啊,当然,脑子快的例外,可以直接跳过之前的一切直接来看即可,只需要你在高中的时候数学成绩还可以那就没啥问题,其实,dp就是规律总结,我们只需要推导出对应题目的数学规律就可以直接操作,可能是一维数组,也可能是二维数组,总体来看二维数组的较多,但是如果能降为的话建议降为,因为如果降为起来你看看时间复杂度就知道咋回事了,那么在这里祝大家能无序的各种看明白,争取能帮助到大家。


全排列题目要求

题目解析

从字符串数组中每次选取一个元素,作为结果中的第一个元素;然后,对剩余的元素全排列

全排列

从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

公式:全排列数f(n)=n!(定义0!=1)

例如:如果是对任意的三个字符进行全排列,也就是3!=6,当然,如果是相同的就只有1次

String s="我爱你";

三个字符,全排列,6中结果

我爱你
我你爱
爱我你
爱你我
你爱我
你我爱

三个相同字符串,就一次

爱爱爱

那么我们要编辑出这种排列方法:

首先判断是否字符串相同:

方案1:

package com.item.action;
public class Demo1 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s = "说说说说说";
    for (int j = 0; j < 10; j++) {
      long start = System.nanoTime();
      char[] cs = s.toCharArray();
      // 我们要判断字符串中是否有不相同的字符
      boolean isf=false;
      for (int i = 0; i < cs.length - 1; i++) {
        if (cs[i] != cs[i + 1]) {
          isf=true;
          break;
        }
      }
      long end = System.nanoTime();
      System.out.println("char数组消耗时间:" + (end - start));
      System.out.println(isf?"字符串不相同":"字符串都相同");
    }
  }
}

消耗时间:

方案2:

package com.item.action;
public class Demo2 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s = "说说说说说";
    for (int j = 0; j < 10; j++) {
      long start = System.nanoTime();
      // 我们要判断字符串中是否有不相同的字符
      boolean isf=false;
      for (int i = 0; i < s.length()-1; i++) {
        if (s.charAt(i) != s.charAt(i+1)) {
          isf=true;
          break;
        }
      }
      long end = System.nanoTime();
      System.out.println("charAt消耗时间:" + (end - start));
      System.out.println(isf?"字符串不相同":"字符串都相同");
    }
  }
}

消耗时间

根据方案1与方案2对比,我们知道charAt相对效率较高,我们使用第二种方法。

全排列示例代码

package com.item.action;
import java.util.ArrayList;
public class Demo3 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s = "说你爱我";
    // 先进行判断是否相同字符串,后进行全排列
    // 我们这里操作的都是char所以使用==,如果使用字符串s.equals(str)
    boolean isf = true;
    for (int i = 0; i < s.length() - 1; i++) {
      if (s.charAt(i) != s.charAt(i + 1)) {
        isf = false;
        break;
      }
    }
    if (isf) {
      System.out.println(s);// 因为只有1种排列
      return;
    }
    // 全排列
    f(s.toCharArray(), 0, s.length() - 1);
  }
  private static void f(char[] cs, int from, int to) {
    // TODO Auto-generated method stub
    // 写递归先写终止条件
    if (from == to) {
      System.out.println(cs);
    }
    for (int i = from; i <= to; i++) {
      // 交换节点
      changeIndex(cs, i, from);
      // 递归·排序
      f(cs, from + 1, to);
      // 还原节点
      changeIndex(cs, from, i);
    }
  }
  private static void changeIndex(char[] cs, int from, int to) {
    // TODO Auto-generated method stub
    char temp = cs[from];
    cs[from] = cs[to];
    cs[to] = temp;
  }
}

六种

判断是否正确

根据【公式:全排列数f(n)=n!(定义0!=1)】判断是否全排列完成。

示例字符串【说你爱我】,4个字。

阶乘可得:

package com.item.action;
public class Demo4 {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    //计算阶乘
    System.out.println(dfs(4));
  }
  private static int dfs(int i) {
    // TODO Auto-generated method stub
    if(i==1) {
      return 1;
    }
    return i*dfs(i-1);
  }
}

阶乘结果:

全排列代码验证:

package com.item.action;
import java.util.ArrayList;
public class Demo3 {
  static ArrayList<char[]> list = new ArrayList<>();
  
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s = "说你爱我";
    // 先进行判断是否相同字符串,后进行全排列
    // 我们这里操作的都是char所以使用==,如果使用字符串s.equals(str)
    boolean isf = true;
    for (int i = 0; i < s.length() - 1; i++) {
      if (s.charAt(i) != s.charAt(i + 1)) {
        isf = false;
        break;
      }
    }
    if (isf) {
      System.out.println(s);// 因为只有1种排列
      return;
    }
    // 全排列
    f(s.toCharArray(), 0, s.length() - 1);
    System.out.println("长度:"+list.size());
  }
  private static void f(char[] cs, int from, int to) {
    // TODO Auto-generated method stub
    // 写递归先写终止条件
    if (from == to) {
      System.out.println(cs);
      list.add(cs);
    }
    for (int i = from; i <= to; i++) {
      // 交换节点
      changeIndex(cs, i, from);
      // 递归·排序
      f(cs, from + 1, to);
      // 还原节点
      changeIndex(cs, from, i);
    }
  }
  private static void changeIndex(char[] cs, int from, int to) {
    // TODO Auto-generated method stub
    char temp = cs[from];
    cs[from] = cs[to];
    cs[to] = temp;
  }
}

验证结果,通过:

相关文章
|
6月前
|
Java
【java】小学生数学练习题目生成系统
小学生数学练习题目生成系统
|
6月前
|
人工智能 算法 Java
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1005 数字游戏
107 0
|
4月前
|
Java
【Java】程序练习1(数组)
【Java】程序练习1(数组)
|
6月前
|
机器学习/深度学习 Java Windows
Java练习-2023-3-29
Java练习-2023-3-29
27 0
|
6月前
|
算法 Java Python
保姆级Java入门练习教程,附代码讲解,小白零基础入门必备
保姆级Java入门练习教程,附代码讲解,小白零基础入门必备
|
6月前
|
存储 搜索推荐 算法
【详识JAVA语言】数组练习
【详识JAVA语言】数组练习
50 1
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1007 印章
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1007 印章
62 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1006 拿金币
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1006 拿金币
66 0
|
6月前
|
算法 Java C语言
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1004 无聊的逗
第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1004 无聊的逗
90 0
|
8天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。