笔试训练(2)

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        StringBuffer s1=new StringBuffer("A");
        StringBuffer s2=new StringBuffer("B");
        process(s1,s2);
        System.out.println(s1);
        System.out.println(s2);
    }
    public static void process(StringBuffer s1,StringBuffer s2){
        s1.append(s2);
        s2=s1;
    }

1)上述程序输出的结果是:AB,B

2)下列不能作为标识符的是:

 标识符 
    A ATRING
    B X3X
    C void,int,double
    D desf

解析: 数字字母下划线以及美元符号,标识符是指用来标识某个实体的一个符号,在不同的应用环境下有不同的含义,况且数字不能在最前面

编程题1:回文串:回文子串_美团笔试题_牛客网

回文串是正着读反着读都是一样的字符串,比如说level和noon等就是回文串,花花非常喜欢这种具有对称美的回文串,在他生日的时候他得到两个礼物分别是字符串A和字符串B但是她非常好奇有没有一种办法将字符串B插入字符串A使其产生的字符串是一个回文串,请你进行寻找有多少种不同的方法使得新串变成一个回文串,你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法;

举个例子:

假设说字符串A="aba",字符串B="b",现在有四种将B插入A的方法:

插在字符串A的第一个字母'a'前面,"baba"不是回文串

插在字符串A的第一个字母'a'后面,发现'abba'是一个回文串

插在字符串A的第二个字母'b'后面,发现'abba'是一个回文串

插在字符串A的第三个字母'a'后面,发现'abab'不是一个回文串

所以说此时的的正确答案是4个

注意事项:

1)在StringBuffer这个对象中,是没有equals方法的我们假设说如果调用了StringBuilder的equals方法,那么就默认调用的是父类的equals方法,比较的是两个对象的地址比如说:

 public static void main(String[] args) {
    StringBuilder S1=new StringBuilder("abc");
    StringBuilder S2=new StringBuilder("abc");
    System.out.println(S1.equals(S2));//这个默认比较的是父类的equals方法
 }

2)我们在StringBuffer中进行调用字符串逆置的时候,不光新接收的stringBuffer指向的字符数组会发生改变,况且来说原来字符串指向的stringBuffer也会发生改变:

  String str1="abcd";
  StringBuilder S1=new StringBuilder(str1);
  StringBuilder S2=S1.reverse();
  System.out.println("==========");
        System.out.println(str1);
        System.out.println(S1);
        System.out.println(S2);

这个程序的打印结果就是

abcd
dcba
dcba

3)StringBuffer还有一个库函数叫做insert方法:

一:第一个参数是你想进行插入的目标位置,第二个参数就是你要进行插入的字符串:

 StringBuffer S1=new StringBuffer("HelloWorld");
 S1.insert(0,"lijiawei");
 System.out.println(S1);

最终咱们程序的打印结果就是:lijiaweiHelloWorld

二:况且来说这个方法也是可以进行插入字符的:

 StringBuffer stringBuffer=new StringBuffer("aaaaa");
 stringBuffer.insert(0,'c');
 System.out.println(stringBuffer);

所以说最终打印的结果是caaaa

所以说它最终会进行替换对应位置的字符,况且会把对应位置的字符向后进行移动:

思路:

一:判断是否回文

如果说只给一个字符串判断它是否是回文串,那么就通过两种方法来进行解决

1)直接进行逆置,判断是否和原来的字符串是相同的

2)定义双指针,一个指向头,一个指向未,让指向头和指向未的字符串都向前进行减减,如果说他们所指向的字符不相等,那么就说明不是回文串

二:找到合适的位置进行插入 

其实我们最本质上纠结的一个问题就是说如何在上述字符串str1的_位置依次插入一个字符串B,然后逐步地进行判断他是否是一个回文串,在定义变量进行++操作

依次再放到1号,2号,3号,4号位置,这个移动元素的过程标志库已经帮我们做好了这件事情了

注意:我们也是可以把对应的字符串放到4号位置且不会出现下标越界的情况,因为这不是一个数组

  StringBuffer buffer=new StringBuffer("abcd");
  buffer.insert(4,'0');
  System.out.println(buffer);

上述程序的运行结果是:

abcd0
import java.util.*;
public class Main{
    public static void main(String[] args){
    Scanner scanner=new Scanner(System.in);
    while(scanner.hasNext()){
        String A=scanner.nextLine();
        String B=scanner.nextLine();
        int count=0;
        for(int i=0;i<=A.length();i++){
           StringBuffer S1=new StringBuffer(A);
            S1.insert(i,B);//插入到对应的位置
           StringBuffer temp=new StringBuffer(S1);
           StringBuffer S2=S1.reverse();//继续宁字符串逆置操作最后在来进行判断是否相等
           if(temp.toString().equals(S2.toString())){
                 count++;
              }
         }
         System.out.println(count);
      }
        
    }
}
import java.util.*;
public class Main{
     public static boolean isTrue(StringBuffer S){
        char[] array=S.toString().toCharArray();
        int left=0;
        int right=array.length-1;
        while(left<=right){
            if(array[left]!=array[right]){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
    public static boolean isTrue(StringBuffer S){
        char[] array=S.toString().toCharArray();
        int left=0;
        int right=array.length-1;
        while(left<right){
            if(array[left]!=array[right]){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
    public static void main(String[] args){
    Scanner scanner=new Scanner(System.in);
    while(scanner.hasNext()){
        String A=scanner.nextLine();
        String B=scanner.nextLine();
        int count=0;
        for(int i=0;i<=A.length();i++){
           StringBuffer S1=new StringBuffer(A);
            S1.insert(i,B);
           if(isTrue(S1)){
               count++;
             }
         }
         System.out.println(count);
      }
        
    }
}

或者我们通过上述的方式进行解答也是可以的

第二题:连续子数组的最大和:连续子数组的最大和_牛客题霸_牛客网​​​​​​

第一种方法:暴力破解

[1,-2,3,10,-4,7,2,-5]

1)他的子数组都有单独的数

2)我们定义一个变量i从初始位置出发,j每次等于i,向后进行++操作,这样就可以求出子数组的最大和,但是他的时间复杂度达到了O(N^2)

我们直接最简单粗暴的方法就是求出所有子数组的最大和,然后更新最大值

 public int FindGreatestSumOfSubArray(int[] array) {
        int sum=0;
        int max=Integer.MIN_VALUE;
        for(int i=0;i<array.length;i++){
             sum=0;
            for(int j=i;j<array.length;j++){
                    sum=sum+array[j];
                if(sum>max){
//把这个条件放在里面就是为了判断单独的某一位数字是否已经大于他的最大值
                    max=sum;
                }
            }
        }
        return max;  
    }
class Solution {
    public int maxSubArray(int[] array) {
        int max=Integer.MIN_VALUE;
         for(int i=0;i<array.length;i++){
            int sum=0;
            for(int j=i;j<array.length;j++){
                if(max<=sum){
                    max=sum;
                }
                 sum=sum+array[j];
            }
        }
        return max;
    }
}

上面的那一种写法是错误的,因为比如说只有一个元素1的时候,第二个循环只执行了一次,没有来得及更新最大值

第二种方法:动态规划

dp[i]:就是元素未array[i]为结尾的连续子数组最大和

它的意思就是说这个值包含两种可能

1)就是包含结尾的这个数array[i];

2)要么就是包含结尾的这个数+前面的包括以array[i-1]为结尾的子数组的最大和

状态方程式:max(dp[i])=getMax(max(dp[i-1]))+array[i],array[i])

所以说我们要进行循环计算每一个dp[i]的值,如果发现dp[i]的值大于最大值,那么max=dp[i]

假设现在有一堆数:

6,-3,-2,7,-15,1,2,2

dp[0]:6

dp[1]:3

(在这里面dp[1]可以进行选择的值有两个,一个是array[1]=-3,一个就是array[1]+dp[0]=3)

dp[2]:6,-3,-2--->1

(在这里面dp[2]可以进行选择的值有两个,一个就是array[2]=-2,一个就是array[2]+dp[1]=1)

dp[3]:6,-3,-2,7   8

(在这里面dp[3]可以进行选择的值有两个,一个就是array[3]=7,一个就是array[3]+dp[2]=8)

但是假设说如果数组元素是这样子的

dp[3]:-6,-3,-2,7     那么此时连续子数组最大和是7,前面的那些数还不如不加,因为加上了也是累赘

所以我们最终的原因就是前面加起来的和和自己本身谁大,万一前面的数比自己本身还小,那么加起来还不如不加

错误写法:

import java.util.*;
public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
       Scanner scanner=new Scanner(System.in);
       int sum=array[0];
       int max=array[0];
       for(int i=1;i<array.length;i++){
            int temp=GetMax(sum+array[i],array[i]);
            if(temp>=max){
                max=temp;
            }
            sum=sum+array[i];
       }
       return max;
    }
    public int GetMax(int a,int b){
        if(a>b) return a;
        else return b;
    }
}

注意:sum不是表示i-1的所有数字的和,而是表示以数字array[i-1]结尾的子数组的最大和

 通不过的用例:-1,1,2,1

dp[0]=-1;

dp[1]=1;(在这里面dp[1]的可能取值有两种,一种是array[1]=1,一种是array[1]+dp[0]=0)

dp[2]=3;(在这里面dp[2]的可能取值有两种,一种是array[2]=2,一种是array[2]+dp[1]=3)

dp[3]=4;(在这里面dp[3]的可能取值有两种,一种是array[3]=1,一种是array[3]+dp[2]=4)

import java.util.*;
public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
       int sum=array[0];
       int max=array[0];
       for(int i=1;i<array.length;i++){
            sum=GetMax(sum+array[i],array[i]);//更新dp[i]的值
            if(sum>=max){
                max=sum;
            }
       }
       return max;
    }
    public int GetMax(int a,int b){
        if(a>b) return a;
        else return b;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值