四個編程題總體算比較簡單,基本都在LeetCode出現過。但是我的速度太慢了,還要加油啊ヾ(◍°∇°◍)ノ゙
牛客快手2020校園招聘秋招筆試–算法B試卷
合法數獨
給定一個數獨板的輸入,確認當前的填法是否合法。
合法的輸入需要滿足以下三個條件:
- 每一行的9個格子中是1-9的9個數字,且沒有重複
- 每一列的9個格子中是1-9的9個數字,且沒有重複
- 9個3*3的小格子中是1-9的9個格子,且沒有重複
:開始意思弄錯了判斷的是能不能填滿81個數,爛費了好多時間。結果是隻要判斷當前的,就很難受。
set判斷當前值,不包含則加入當前值,包含代表重複,則返回false
obj.dfs(s,0,0);
System.out.println(obj.answer);
判斷81個能否都填滿。
import java.util.*;
public class Main {
boolean answer = false;
private boolean get(char str[][]){
for (int x=0;x<9;x++){
Set<Character> set = new HashSet<>();
for (int y = 0; y < 9; y++) {
if (str[x][y] != 'X' && !set.contains(str[x][y]))
set.add(str[x][y]);
else if(set.contains(str[x][y]))
return false;
}
}
for (int x=0;x<9;x++){
Set<Character> set = new HashSet<>();
for (int y = 0; y < 9; y++) {
if (str[y][x] != 'X' && !set.contains(str[y][x]))
set.add(str[y][x]);
else if(set.contains(str[y][x]))
return false;
}
}
for (int x=0;x<3;x++){
for (int y=0;y<3;y++){
Set<Character> set = new HashSet<>();
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if(str[x*3+i][y*3+j]!='X' && !set.contains(str[x*3+i][y*3+j]))
set.add(str[x*3+i][y*3+j]);
else if(set.contains(str[x*3+i][y*3+j]))
return false;
}
}
}
}
return true;
}
public static void main(String[] args) {
Main obj = new Main();
String []mm=new String[9];
char[][] s= new char [9][9];
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 9; i++) {
mm[i]=scanner.nextLine();
for (int j = 0; j < 9; j++) {
s[i][j]=mm[i].charAt(j) ;
}
}
// obj.dfs(s,0,0);
// System.out.println(obj.answer);
System.out.println(obj.get(s));
}
private void dfs(char [][] str,int x,int y){
if (y==9){
x++;
y=0;
}
if(x>8){
this.answer=true;
return ;
}
while (x<=8){
if(str[x][y]=='X')
break;
y++;
if (y==9){
x++;
y=0;
}
if(x>8){
this.answer=true;
return ;
}
}
Set<Character> set = new HashSet<>();
for (int i = 1; i <= 9; i++) set.add((char)(i+'0'));
for (int i = 0; i < 9; i++) {
if (str[i][y] != 'X' && set.contains(str[i][y]))
set.remove(str[i][y]);
}
for (int i = 0; i < 9; i++) {
if (str[x][i] != 'X' && set.contains(str[x][i]))
set.remove(str[x][i]);
}
int x1=x/3 * 3,y1=y/3 * 3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (str[x1+i][y1+j] != 'X' && set.contains(str[x1+i][y1+j])) {
set.remove(str[x1 + i][y1 + j]);
}
}
}
for (Character character : set){
str[x][y]=character;
dfs(str,x,y+1);
str[x][y]='X';
}
return ;
}
}
分解質因數
我們知道每一個大於1的整數都一定是質數或者可以用質數的乘積來表示,如10=25。現在請設計一個程序,對於給定的一個(1,N] 之間的正整數(N取值不超過10萬),你需要統計(1,N] 之間所有整數的質數分解後,所有質數個數的總個數。舉例,輸入數據爲6,那麼滿足(1,6] 的整數爲2,3,4,5,6,各自進行質數分解後爲:2=>2,3=>3,4=>22,5=>5,6=>2*3。對應的質數個數即爲1,1,2,1,2。最後統計總數爲7
輸入描述:
輸入數據包含1行,爲一個大於1的整數(不超過10萬)。
輸出描述:
輸出小於等於該數的所有整數質數分解後的總個數。
示例1
輸入
6
輸出
7
:肯定有更好的方法不過我是暴力的…當時當算超時了就直接往數組存打出來的質數,然後優化後面的找質因子的代碼,好結果都沒必要,可能100000太小了把。
public class Main {
public static void main(String[] args) {
List<Integer> set = new ArrayList<>();
for (int i = 2; i < 100000; i++) {
int flag=0;
for (int j = 2; j <= (int)Math.sqrt(i); j++) {
if(i%j==0) {
flag=1;
break;
}
}
if(flag == 0)
set.add(i);
}
int n = 100000,sum=0;
Scanner scanner = new Scanner(System.in);
n=scanner.nextInt();
scanner.close();
for (int i=2;i<=n;i++){
int ii=i;
while (ii!=1){
for (Integer a: set){
if(ii%a==0){
ii/=a;
sum++;
break;
}
if(a>ii)
break;
}
}
}
System.out.println(sum);
}
}
Levenshtein distance
已知兩個字符串strA和strB,求將strA轉換成strB所需的最小編輯操作次數。許可的編輯操作包括將一個字符替換成另一個字符,插入一個字符,刪除一個字符。
輸入描述:
任意字符串strA和strB,其中第一行爲strA,第二行爲strB
輸出描述:
最小編輯操作次數
示例1
輸入
FreshMeat
FishAndMeat
輸出
5
: 演算找出規律(說起來輕鬆做起來難o(╥﹏╥)o)
1 當前字符相等strA[j] 等於 strB[i] ,則當前dp值爲左上角dp值
2 字符不等,左dp值 != 上dp值, 當前dp值爲min(左dp,上dp)+1
3 字符不等,左dp值 等於 上dp值, 當前dp值爲 左上角dp值 +1 此種容易想錯
// FreshMeat
// FishAndMeat
// 0 1 2 3 4 5 6 7 8 9
// 1 0 1 2 3 4 5 6 7 8
// 2 1 1 2 3 4 5 6 7 8
// 3 2 2 2 2 3 4 5 6 7
// 4 3 3 3 3 2 3 4 5 6
// 5 4 4 4 4 3 3 4 5 6
// 6 5 5 5 5 4 4 4 5 6
// 7 6 6 6 6 5 5 5 5 6
// 8 7 7 7 7 6 5 6 6 6
// 9 8 8 7 8 7 6 5 6 7
// 10 9 9 8 8 8 7 6 5 6
// 11 10 10 9 9 9 8 7 6 5
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String strA = scanner.nextLine();
String strB = scanner.nextLine();
scanner.close();
int up=0,down=0;
int lenA = strA.length();
int lenB = strB.length();
int dp[][]=new int[lenB+1][lenA+1];
dp[0][0]=0;
for (int i = 0; i <= lenB; i++) dp[i][0]=i;
for (int i = 0; i <= lenA; i++) dp[0][i]=i;
for (int ii = 1; ii <= lenB; ii++) {
int i=ii-1;
for (int jj=1;jj<=lenA;jj++){
int j=jj-1;
if(strB.charAt(i) == strA.charAt(j)){
dp[ii][jj]=dp[i][j];// 相等爲左上角dp
}else if(dp[ii][j] == dp[i][jj]){
dp[ii][jj]=dp[i][j]+1;//上方的值 == 左方的值 當前值=左上值+1
}else {
//上方的值 != 左方的值 當前值=min(左值,上值)+1
dp[ii][jj]=Math.min(dp[ii][j],dp[i][jj])+1;
}
}
}
System.out.println(dp[lenB][lenA]);
}
}
單詞反轉
輸入一個英文句子, 詞之間有1個或者若干個空格,句子以英文標點".“結尾。
要求顛倒該句子中的詞語順序,並且詞之間有且只有一個空格,結尾仍然是”.",結尾的"."與前一個單詞之間無空格。
輸入描述:
I love you .
輸出描述:
you love I.
示例1
輸入
I love you.
輸出
you love I.
題目本意應該是雙指針遍歷,不過有api(逃)
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String a = scanner.nextLine();
int flag = 0;
for (int i=a.length()-1;i>=0;i--){
if(a.charAt(i) == '.'){
a=a.substring(0,i );
break;
}
}
String b="";
String str[]=a.trim().split(" +");
for(int i=str.length-1;i>0;i--){
b=b+str[i]+" ";
}
b=b+str[0]+".";
System.out.println(b);
}
}