每日一题Day18~Day24

每日一题 Day18

A、count(*)一定可以返回数值,如果t1中没有数据,返回0

B、max返回null可能有两种情况 1)t1中没有数据  2)col1字段全部都是null

C、concat是字符串拼接函数,如果拼接的其中一个字符串为null,结果就是null


A、默认创建的外键是严格模式(必须在主表中,关联的键有该数据)

      其他模式外键可以为空

B、候选键:可以标识数据的唯一性的最小集



top,是sql srever中的关键字,用于求前n条数据(如果要查从m条到n条,要写子查询)

语法:select top n 查询字段 from……




A、phoneno是数字组成(使用数值数据类型),和字符串可以比较,但是会进行类型转换(有点耗时)

B、模糊匹配,可以使用索引

C、使用函数,不会再使用索引,全部扫i描(全部数据遍历),函数本身的执行也需要耗时




RDBMS是关系型数据库
D、hadoop是大数据方向的数据库,不是关系型 


题目:HJ37 统计每个月兔子的总数

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){//多组输入
            int m=sc.nextInt();
            System.out.println(num(m));
            
        }
    }
    public static int num(int m){
        if(m<=2){
            return 1;
        }
        return num(m-1)+num(m-2);
    }
}

题目:HJ71 字符串通配符

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNextLine()){
            String t=sc.nextLine();//通配符字符串
            String s=sc.nextLine();//字符串
            System.out.println(match(t,s));
        }
    }
    public static boolean match(String t,String s){
        //因为要一个字符一个字符匹配,所以先拆成一个个字符放到数组中
        char[] ct=t.toCharArray();
        char[] cs=s.toCharArray();
        int lt=ct.length;
        int ls=cs .length;
        boolean[][] dp=new boolean[ls+1][lt+1];//长:ls 宽:lt
        dp[0][0]=true;//base case
        for(int i=0;i<=ls;i++){//i用来遍历字符串数组
            for(int j=1;j<=lt;j++){//j用来遍历通配符数组
                if(ct[j-1]=='*'){//当通配符时*时(要单独判断,因为*可以匹配多个字符)
                    if(i==0){此时没有字符串与*匹配
                        dp[i][j]=dp[i ][j-1];//此时前一个是啥就是啥
                    }else{
                        if(cs[i-1]=='.'||cs[i-1]>='A'&&cs[i-1]<='Z'
                           ||cs[i-1]>='a'&&cs[i-1]<='z'
                           ||cs[i-1]>='0'&&cs[i-1]<='9'){
                            //如果截止到*的通配符和当前要匹配字符的前一个字符匹配成功,则为true(此时*匹配多个字符)
                            //如果*之前的通配符和要匹配字符匹配成功,则也为true(此时*匹配一个字符)
                            
                            dp[i][j]=dp[i-1][j]||dp[i][j-1];
                        }
                    }
                }else{//当通配符不是*时
                    if(i>0&&defs(ct[j-1],cs[i-1])){//defs方法,用来看通配符表达式和字符串是不是相等
                        //如果当前字符匹配成功,要看一下前面的字符是否匹配成功,都成功才成功

                        dp[i][j]=dp[i-1][j-1];
                    }
                }
            }
        }
        return dp[ls][lt];
    }
    public static boolean defs(char t,char s){//判断字符是否匹配
        if(t=='?') return true;
        if(t>='a'&&t<='z'){
            t=(char)(t-'a'+'A');//把小写字母转换成大写字母
        }
        if(s>='a'&&s<='z'){
            s=(char)(s-'a'+'A');
        }
        return s==t;
    }
    
}


 每日一题 Day19

A、链表的存储数据可以不一致,但逻辑顺序必须一致

B、链表的存储空间也是不连续的



顺序存储结构:顺序表

二叉树中只有完全二叉数可以使用顺序表存储 

A、非完全二叉树只能采用链式存储

B、堆是一个完全二叉树,可以使用数组存储

C、D、队列和栈都属于顺序表


递归函数的终止条件:函数调用过程中有一个分支直接return不会一直调用下去




都列出来,看是小堆还是大堆,都不符合就不是堆



此时内存中放不下所有要排序的数据,需要进行外部排序,借助外部的空间(磁盘)进行排序。通常外部排序利用:多路归并排序

先将1GB分为大小相等的20份,每份大小为50MB,依次将每份数据读入内存中进行排序(内部排序:快排等),然后在外部空间进行这20份的归并过程


树的深度:最大的节点高度,从根节点开始算第一层


题目:36889-查找两个字符串a,b中的最长公共子串  

import java.util.*;

public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            String str1=sc.nextLine();
            String str2=sc.nextLine();
            if(str1.length()<str2.length()){
                System.out.println(getMaxSubstr(str1,str2));               
            }else{
                System.out.println(getMaxSubstr(str2,str1));
            }
        }
    }
    //假设str1长度短
    public static String getMaxSubstr(String str1,String str2){
        char[]arr1=str1.toCharArray();
        char[]arr2=str2.toCharArray();
        int len1=arr1.length;
        int len2=arr2.length;
        //最长子串的起始位置
        int start=0;
        //最长的子串长度
        int maxLen=0;
        //多增加一行一列,作为辅助状态
        int[][] maxSubLen=new int[len1+1][len2+1];
        //以str1的第i个字符结尾和以str2的第j个字符结尾的最长公共字串的长度
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                //如果第i个字符和第j个字符相等,则进行累加
                if(arr1[i-1]==arr2[j-1]){
                    maxSubLen[i][j]=maxSubLen[i-1][j-1]+1;
                    //更新
                    if(maxLen<maxSubLen[i][j]){
                        maxLen=maxSubLen[i][j];
                        start=i-maxLen;
                    }
                }
            }
        }
        return str1.substring(start,start+maxLen);
    }
}

 题目:36846-汽水瓶

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            int num=sc.nextInt();
            if(getNum(num)!=0){
                System.out.println(getNum(num));
            }
        }
    }
    public static int getNum(int num){//num为空瓶的个数
        //汽水的个数
        int sum=0;
        while(num>1){
            //兑换的汽水的个数num/3
            sum+=num/3;
            //剩余的空瓶子
            num=num/3+num%3;
            if(num==2){
                //借一瓶
                sum++;
                break;
            }
        }
        return sum;     
    }
}


每日一题 Day20



 栈和队列插入的时间复杂度都是O( 1 )



叶子节点的个数=度为2的节点个数+1


当前序遍历和中序遍历序列相同时,一定是一个单方向树(链表)


建堆:是从最后一个非叶子节点开始进行元素的shiftDown操作



近乎有序的数组中,冒泡排序是比较优秀的,当发现元素没有交换时,认为此时数组已经有序,排序退出

归并和堆排是比较稳定的:为O(nlogn)



 题目:36899-公共字串计算  

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        String str1=sc.nextLine();
        String str2=sc.nextLine();
        System.out.println(getMaxLen(str1,str2));       
    }
    public static int getMaxLen(String str1,String str2){
        char[]arr1=str1.toCharArray();
        char[]arr2=str2.toCharArray();
        int len1=arr1.length;
        int len2=arr2.length;
        int maxLen=0;
        int[][]maxSubLen=new int[len1+1][len2+1];
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(arr1[i-1]==arr2[j-1]){
                    //状态转移方程
                    maxSubLen[i][j]=maxSubLen[i-1][j-1]+1;
                }      
                //更新最大值
                if(maxLen<maxSubLen[i][j]){
                    maxLen=maxSubLen[i][j];
                }
            }
        }
        return maxLen;
    }
}

题目:36836-字符串反转

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        String str=sc.nextLine();
        char[]arr=str.toCharArray();
        int len=arr.length;
        int i=0;
        int j=len-1;
        while(i<j){
            char tmp=arr[i];
            arr[i]=arr[j];
            arr[j]=tmp;
            i++;
            j--;
        }
        String s=new String(arr);
        System.out.println(s);
    }
}

每日一题 Day21






 B、循环队列用的是数组


 哈夫曼树是带权值的树(与元素大小顺序无关)

增大装载因子会增加元素冲突,使查找变慢


堆排序的方式:先将0位置元素和最后位置元素交换,然后继续在剩下的元素中调整为最大堆


 

最坏情况下:

希尔排序:比O(NlogN)大

快排:当出现大量重复元素或者数组几乎有序时,递归树退化为链表,为O(N^2)

堆排:是一个稳定的排序O(NlogN)

冒泡:O(N^2)


题目:MP3光标位置

import java.util.*;
public class Main{
     public static void main(String[]args){
         Scanner sc=new Scanner(System.in);
         String numStr=sc.nextLine();
         String orderStr=sc.nextLine();
         mouseMove(numStr,orderStr);
    
     }
     public static void mouseMove(String numStr,String orderStr){
         //歌曲数量
         int n=Integer.parseInt(numStr);
         //指令数组:UD
         char[] order=orderStr.toCharArray();
         //当前鼠标所在的位置
         int mouse=1;//光标初始的位置为第1首歌
         //显示列表所在的起始位置
         int first=1;
         //指令处理
         //歌曲数量n<=4时
         if(n<=4){
             for(int i=0;i<order.length;i++){
                 //光标在第一首歌曲上时,按Up键光标挪到最后一首歌曲
                 if(mouse==1&&order[i]=='U'){
                     mouse=n;
                 }
                 //光标在最后一首歌曲时,按Down键光标挪到第一首歌曲
                 else if(mouse==n&&order[i]=='D'){
                    mouse=1;
                 }
                 //其他情况下用户按Up键,光标挪到上一首歌曲
                 else if(order[i]=='U'){
                     mouse--;
                 }
                 //用户按Down键,光标挪到下一首歌曲
                 else if(order[i]=='D'){
                     mouse++;
                 }
             }
             //输出
             //打印当前的显示列表
             for(int i=1;i<n;i++){
                 System.out.print(i+" ");
             }
             System.out.println(n);
             //打印当前歌曲
             System.out.println(mouse);
         }
         //歌曲数量n>4时
         else{
             for(int i=0;i<order.length;i++){
                 //屏幕显示的是第一页(即显示第1 – 4首)时,
                 //光标在第一首歌曲上,用户按Up键后,屏幕要显示最后一页(即显示第7-10首歌),
                 //同时光标放到最后一首歌上。
                 if(first==1&&mouse==1&&order[i]=='U'){
                     //最后一页的起始位置为歌曲数-3
                     first=n-3;
                     mouse=n;
                 }
                 //屏幕显示最后一页时,光标在最后一首歌曲上,
                 //用户按Down键,屏幕要显示第一页,光标挪到第一首歌上。
                 else if(first==n-3&&mouse==n&&order[i]=='D'){
                     first=1;
                     mouse=1;
                 }
                 //屏幕显示的不是第一页时,光标在当前屏幕显示的第一首歌曲时,
                 //用户按Up键后,屏幕从当前歌曲的上一首开始显示,光标也挪到上一首歌曲
                 else if(first!=1&&mouse==first&&order[i]=='U'){
                     first--;
                     mouse--;
                 }
                 //光标当前屏幕的最后一首歌时的Down键处理也类似
                 else if(first!=n-3&&mouse==first+3&&order[i]=='D'){
                     first++;
                     mouse++;
                 }
                 //其他情况,不用翻页,只是挪动光标就行。
                 else if(order[i]=='U'){
                     mouse--;
                 }
                 else if(order[i]=='D'){
                     mouse++;
                 }                 
             }
             //输出
             //打印当前的显示列表
             for(int i=first;i<first+3;i++){
                 System.out.print(i+" ");
             }
             System.out.println(first+3);
             //打印当前歌曲
             System.out.println(mouse); 
         }
     }
 }

题目:洗牌

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        int groups=sc.nextInt();
        for(int i=0;i<groups;i++){
            //读入每组数据
            int n=sc.nextInt();
            int k=sc.nextInt();
            int[] cards=new int[2*n];
            for(int j=0;j<2*n;j++){
                cards[j]=sc.nextInt();
            }
            //洗牌
            playCard(cards,n,k);
        }
    }
    //n为牌数一半,k为洗牌次数
    public static void playCard(int[] cards,int n,int k){
        //编号为i是牌,最后放到2*i位置
        //编号为i+n的牌最后放到2*i+1位置
        for(int i=0;i<k;i++){
            //一次洗牌的过程
            int [] newCards=new int [cards.length];
            for(int j=0;j<n;j++){
                //遍历编号为0~n-1的牌
                newCards[2*j]=cards[j];
                newCards[2*j+1]=cards[j+n];
            }
            cards=newCards;
        }
        //洗完之后从上往下打印
        printCard(cards);
    }
    public static void printCard(int[]cards){
        for(int i=0;i<cards.length-1;i++){
            System.out.print(cards[i]+" ");
        }
        System.out.println(cards[cards.length-1]);
    }
}

每日一题 Day22



 


 


 

 


用到队列的遍历只有层序遍历 




两个有序的子区间个数都为n,最好的情况为第二个区间都比第一个区间大,只需要比较n次即可


快排:每当交换一次元素,就会产生一个新的逆序对 

简单插入排序和简单选择排序会减少逆序对

冒泡排序是交换相邻的元素,不一定会产生逆序对


   题目:找出字符串中第一个只出现一次的字符

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            String str=sc.nextLine();
            find(str);
        }
    }
    public static void find(String str){
        char[] arr=str.toCharArray();
        int[] check=new int[128];
        boolean flg=false;
        for(int i=0;i<arr.length;i++){
            check[arr[i]]++;
        }
        for(int i=0;i<arr.length;i++){
            if(check[arr[i]]==1){
                System.out.println(arr[i]);
                flg=true;
                break;
            }
        }
        if(flg==false){
            System.out.println(-1);
        }
    }
}

题目:小易的升级之路

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            int n=sc.nextInt();//怪物的数量
            int x=sc.nextInt();//小易的初始能力值
            int[] nums=new int[n];//怪物的防御力
            for(int i=0;i<n;i++){
                nums[i]=sc.nextInt();
                if(nums[i]<=x){
                    x+=nums[i];
                }
                else{
                    x+=gcd(x,nums[i]);
                }
            }
            System.out.println(x);

        }
    }
     public static int gcd(int a,int b){//求最大公约数
        int c;
        while((c=a%b)!=0){
            a=b;
            b=c;
        }
        return b; 
    }
}


每日一题 Day23

 




递归次数与初始数据的排列次序有关 




 


平均查找长度=查找次数/数组的元素个数



 

 


题目:计算字符串的编辑距离

 

import java.util.*;
public class Main{
    public static void main(String[]args){
        Scanner sc=new Scanner(System.in);
        while(sc.hasNext()){
            String str1=sc.nextLine();
            String str2=sc.nextLine();
            System.out.println(getDistance(str1,str2));
        }
    }
    public static int getDistance(String str1,String str2){
        char[] wd1=str1.toCharArray();
        char[] wd2=str2.toCharArray();
        int len1=wd1.length;
        int len2=wd2.length;
        //编辑距离矩阵
        int[][] dist=new int[len1+1][len2+1];
        //初始状态:
        //从i个字符变成0个字符,需要删除i个字符:F[i,0]=i
        //从0个字符变成j个字符,需要插入j个字符:F[0,j]=j
        for(int i=0;i<=len1;i++){
            dist[i][0]=i;
        }
        for(int j=0;j<=len2;j++){
            dist[0][j]=j;
        }
        //状态转移
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                //首先求出插入和删除的最小值
                dist[i][j]=Math.min(dist[i-1][j],dist[i][j-1])+1;
                //再和替换作比较
                if(wd1[i-1]==wd2[j-1]){//此时不需要替换
                    dist[i][j]=Math.min(dist[i][j],dist[i-1][j-1]);
                }else{//此时需要替换
                    dist[i][j]=Math.min(dist[i][j],dist[i-1][j-1]+1);
                }
            }
        }
        return dist[len1][len2];
    }
}

题目:微信红包

import java.util.*;

public class Gift {
    public int getValue(int[] gifts, int n) {
        Arrays.sort(gifts);
        int mid=gifts[n/2];
        int count=0;
        //统计中间位置数据出现的次数
        for(int g:gifts){
            if(g==mid){
                count++;
            }
        }
        if(count>n/2){
            return mid;
        }else{
            return 0;
        }
    }
}
public class Gift {
    public int getValue(int[] gifts, int n) {
        // write code here
        Map<Integer,Integer>map=new HashMap<>();
        for(int g:gifts){
            if(map.containsKey(g)){
                map.put(g,map.get(g)+1);
            }else{
                map.put(g,1);
            }
            if(map.get(g)>=n/2){
                return g; 
            }
        }
        return 0;
    }
}


每日一题 Day24

 








 


每进行一次快排,标定点一定处在最终位置

 

进行两次快排,则至少有两个元素到达最终位置



 题目:迷宫问题

import java.util.*;
import java.io.*;
class Node{
    int x;
    int y;
    public Node(int x,int y){
        this.x=x;
        this.y=y;
    }
}
public class Main{
public static void main(String[] args) { 
    Scanner sc=new Scanner(System.in);
    while(sc.hasNext()) { 
        int row = sc.nextInt();
        int col = sc.nextInt();
        //创建迷宫矩阵 
        int[][] mat = new int[row][col]; 
        //读入迷宫数据 
        for(int i = 0; i < row; i++) {
            for(int j = 0; j < col; j++) {
                mat[i][j] = sc.nextInt(); 
            } 
        }
        //搜索最短路径 
        ArrayList<Node> path = new ArrayList<>(); 
        ArrayList<Node> minPath = new ArrayList<>();
        int[][] book = new int[row][col]; 
        getMinPath(mat, row, col, 0, 0, book, path, minPath); 
        //打印最短路径 
        for(Node n : minPath) { 
            System.out.println("(" + n.x + "," + n.y + ")"); 
        } 
    } 
}
    //mat表示迷宫矩阵;x,y为当前位置
    //book为标记矩阵,标记当前位置是否走过
    //path保存路径中的每个位置
    //minpath保存最小路径
    public static void getMinPath(int[][] mat,int row,int col,
        int x,int y,int[][]book,ArrayList<Node>path,ArrayList<Node>minPath){
        //判断(x,y)是否越界,是否走过,是否有障碍
        if(x<0||x>=row||y<0||y>=col
           ||book[x][y]==1||mat[x][y]==1){
            return;
        }
        //把当前位置存入路径中
        path.add(new Node(x,y));
        //标记当前位置
        book[x][y]=1;
        //判断当前位置是否为目的位置
        if(x==row-1&&y==col-1){
            //如果当前位置为目的位置,证明找到了一条路径
            //此时判断当前路径是否为最短路径
            if(minPath.isEmpty()||path.size()<minPath.size()){
                //更新更短路径
                minPath.clear();
                for(Node n:path){
                    minPath.add(n);
                }
            }
        }
        //继续搜索(x,y)的上下左右四个方向
        getMinPath(mat,row,col,x+1,y,book,path,minPath);
        getMinPath(mat,row,col,x-1,y,book,path,minPath);
        getMinPath(mat,row,col,x,y-1,book,path,minPath);
        getMinPath(mat,row,col,x,y+1,book,path,minPath);
        //把当前位置从路径中删掉,寻找新的路径
        path.remove(path.size()-1);
        book[x][y]=0;
    }       
}

题目:年终奖

import java.util.*;

public class Bonus {
    public int getMost(int[][] board) {
        int row=board.length;
        int col=board[0].length;
        //处理第一行:只能从左向右走
        for(int i=1;i<col;i++){
            board[0][i]+=board[0][i-1];
        }
        //处理第一列:只能从上向下走
        for(int i=1;i<row;i++){
            board[i][0]+=board[i-1][0];
        }
        //剩余位置
        for(int i=1;i<row;i++){
            for(int j=1;j<col;j++){
                board[i][j]+=Math.max(board[i-1][j],board[i][j-1]);
            }
        }
        return board[row-1][col-1];     
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值