牛客网刷题笔记(字符串、约数的个数)

开始记录刷题笔记之前先推荐一下自己的学习博客,希望能够有更多的java学习者一起学习一起分享。
个人博客地址 其中很有用的,也有的会后期更新的,一起学习吧。

题目一描述:
输入n个整数,依次输出每个数的约数的个数
题目链接
题目输入是两部分:

5
1 3 4 6 12

题目一分析:
根据题目的要求:
第一行输入的是求几个数的因数,第二行是求哪个数的因数,先要有读取数据的BufferedReader对象和InputStreamReader对象,另外输入数据的长度
(1<=Num<=1000000000),因此应使用Long类型进行数据接收。
求一个数的因数,如果从1循环到该数判断因数的个数或者使用一半的数据判断因数,将会导致时间复杂度过大,因此采用Math.sqrt(n)或者采用ii4算一个因子,结果是5.

代码如下:

import java.io.*;

public class Main{
    public static void main(String[] args)throws Exception{
    //数据读取流
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        //读取数据个数
        long n = Long.valueOf(bf.readLine());
        //将每个数据拆分放入数组
        String[] nums = bf.readLine().split(" ");
        StringBuffer sb = new StringBuffer();
        //循环求每个数的因数
        for(int i=0;i<n;i++){
            sb.append(getNum(Long.valueOf(nums[i])));
            sb.append("\n");
        }
        System.out.print(sb.toString());
    }
    //求一个数的因数
    public static int getNum(Long num){
        if(num==1)return 1;
        int res = 0;
        int i=1;
        for(;i*i<num;i++){
            if(num%i==0)res+=2;
        }
        //对于平方的计算只算1个因数
        if(i*i==num)res++;
        return res;
    }
}

题目二描述:
给定一个字符串,找出最长的不具有重复字符的子串的长度。例如,“abcabcbb”不具有重复字符的最长子串是“abc”,长度为3。对于“bbbbb”,最长的不具有重复字符的子串是“b”,长度为1。
题目链接
题目二分析:
对已数组重复元素或者字符串重复字符,一般都会采用HashMap数据结构记录所有的字符,对于字符串的子串问题会采用移动窗解决。

HashMap记录当前的字符以及字符出现的位置,如果已经出现过当前字符,那么将窗口的左边指针移动到该字符出现位置的下一个位置上;
如果没有出现,那么记录当前位置以及当前字符;
每次计算当前的窗的大小,记录所有窗中最大的窗。

代码如下:

import java.util.*;
import java.lang.Math;
public class Solution {
    /**
     * 
     * @param s string字符串 
     * @return int整型
     */
    public int lengthOfLongestSubstring (String s) {
        // write code here
        if(s.length()<=0)return 0;
        //记录当前的字符,以及字符所在的位置
        HashMap<Character,Integer> map = new HashMap<>();
        //当前元素的位置。也是窗口的右指针
        int index = 0;
        //记录当前的最大窗
        int max = 0;
        //记录窗的左边指针
        int left = 0;
        for(;index<s.length();index++){
            char c = s.charAt(index);
            //窗口左指针移动规则,当前元素存在,则左指针选择性右移
            left = Math.max(left,map.containsKey(c)?map.get(c)+1:0);
            //窗口最大记录
            max = Math.max(max,index-left+1);
            //当前字符记录
            map.put(c,index);
        }
        return max;
    }
}

题目三描述:
找出给出的字符串S中最长的回文子串。假设S的最大长度为1000,并且只存在唯一解。
题目链接
题目三分析:
(参考别人的思路)找出串中最长的回文子串,每个串从中间进行判断,分为奇数串和偶数串,奇数串中间位置只有一个,偶数串中间位置有两个,从中间位置向两边扩展比较,记录最长串的左边界和右边界,最后返回即可。
代码如下:

import java.util.*;
public class Solution {
    int left ;//左边界
    int right ;//右边界
    int len ;//最长的回文串
    public String longestPalindrome (String s) {
        // write code here
        if(s.length()<=1)return s;
        for(int i=0;i<s.length();i++){
            judge(s,i,i);
            judge(s,i,i+1);
        }
        return s.substring(left,right+1);
    }
    public void judge(String ss ,int sta,int en){
        //如果是回文,边界向两边扩展
        while(sta>=0&&en<ss.length()&&ss.charAt(sta)==ss.charAt(en)){
            sta--;
            en++;
        }
        //如果当前的左右边界长大于之前记录的长度,更新左右边界以及最大长度值
        if(en-sta-1>len){
            left = sta+1;
            right = en - 1;
            len = en-sta-1;
        }
    }

}

你可能感兴趣的:(复习时使用)