1.[编程题]左右最值最大差
给定一个长度为N(N>1)的整型数组A,可以将A划分成左右两个部分,左部分A[0..K],右部分A[K+1..N-1],K可以取值的范围是[0,N-2]。求这么多划分方案中,左部分中的最大值减去右部分最大值的绝对值,最大是多少?
给定整数数组A和数组的大小n,请返回题目所求的答案。
测试样例:
[2,7,3,1,1],5
返回:6
import java.util.*;
public class MaxGap {
public int findMaxGap(int[] A, int n) {
// write code here
int max=-1;
int min;
for(int i=0;i<n;i++){
if(A[i]>max){
max=A[i];
}
}
min=A[0]>A[n-1]?A[n-1]:A[0];
return max-min;
}
}
这个题还有些问题
2.[编程题]出专辑
你作为一名出道的歌手终于要出自己的第一份专辑了,你计划收录 n 首歌而且每首歌的长度都是 s 秒,每首歌必须完整地收录于一张 CD 当中。
每张 CD 的容量长度都是 L 秒,而且你至少得保证同一张 CD 内相邻两首歌中间至少要隔 1 秒。
为了辟邪,你决定任意一张 CD 内的歌数不能被 13 这个数字整除,那么请问你出这张专辑至少需要多少张 CD ?
输入描述:
每组测试用例仅包含一组数据,每组数据第一行为三个正整数 n, s, L。 保证 n ≤ 100 , s ≤ L ≤ 10000
输出描述:
输出一个整数代表你至少需要的 CD 数量。
输入例子:
7 2 6
输出例子:
4
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int s=sc.nextInt();
int L=sc.nextInt();
int cd=0;//需要的CD数
int cd_s=(L+1)/(s+1);//每张CD可以放的歌曲数
if(cd_s>n){//CD可以放的歌曲数大于总共的歌曲数
if(n%13==0)//歌曲数是13的倍数,不能只放在一张CD中
{cd=2;}
else
{cd=1;}
}
else{//总共的歌曲数大于每张CD可以放的歌曲数
if(cd_s%13==0)//每张CD可以放的歌曲数是13的倍数
cd_s--;//将每张CD可以放的歌曲数减1
if(n%cd_s==0)//总歌曲数刚好是每张CD可以放的歌曲数的整数倍
cd=n/cd_s;
if(n%cd_s!=0){//不能整存时
if((n%cd_s)%13==0){//多出来的零头是13的倍数
if((cd_s-1)%13==0&&(cd_s-n%cd_s)==1)//从放满的CD中拿出来一个后,原来放满的CD变成13的倍数,而且零头那边只剩了一个位置
cd=n/cd_s+2;
else
cd=n/cd_s+1;//可以从放满的CD中拿出来一个,让零头不是13的倍数,这样就不用多加一张CD了
}else
cd=n/cd_s+1;
}
}
System.out.println(cd);
}
}
这道题很简单,但是要考虑的情况很多,测试用例总是不能完全通过。
3.[编程题]字符混编
A、B和C。如果C包含且仅包含来自A和B的所有字符,而且在C中属于A的字符之间保持原来在A中的顺序,属于B的字符之间保持原来在B中的顺序,那么称C是A和B的混编。实现一个函数,判断C是否是A和B的混编。
给定三个字符串A,B和C,及他们的长度。请返回一个bool值,代表C是否是A和B的混编。保证三个串的长度均小于等于100。
测试样例:
"ABC",3,"12C",3,"A12BCC",6
返回:true
解题思路:
把这道题转换成最长公共子序列的问题。
因为“C包含且仅包含来自A和B的所有字符”,也就是说C中有所有A、B的字符,分别求出AC、BC的最长公共子序列应该分别等于A、B的长度,且相加后为C的长度
import java.util.*;
import java.util.Scanner;
public class Mixture {
public boolean chkMixture(String A, int n, String B, int m, String C, int v) {
// write code here
int x=LCS(A,C);
int y=LCS(B,C);
if(x==n&&y==m&&x+y==v){
return true;
}else
return false;
}
public static int LCS(String x,String y){
int m=x.length();
int n=y.length();
int dp[][]=new int[m+1][n+1];
for(int i=0;i<=m;i++){
dp[i][0]=0;
}
for(int j=0;j<=n;j++){
dp[0][j]=0;
}
for(int j=1;j<=n;j++){
for(int i=1;i<=m;i++){
if(x.charAt(i-1)==y.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=(dp[i][j-1]>=dp[i-1][j]?dp[i][j-1]:dp[i-1][j]);
}
}
}
return dp[m][n];
}
}
4.[编程题]跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
对于本题,前提只有 一次 1阶或者2阶的跳法。
a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);
b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)
c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2)
d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2
e.可以发现最终得出的是一个斐波那契数列:
| 1, (n=1)
f(n) = | 2, (n=2)
public class Solution {
public int JumpFloor(int target) {
if(target==1||target==2){
return target;
}else if(target<1){return -1;}
else{
return JumpFloor(target-1)+JumpFloor(target-2);
}
}
}
但是能用迭代就不要用递归哦
public class Solution {
public int JumpFloor(int target) {
if(target==1||target==2){
return target;
}
int jumpNum=0;//跳法
int numMinusOne=2;//台阶数减1的跳法
int numMinusTwo=1;//台阶数减2的跳法
for(int i=3;i<=target;i++){
jumpNum=numMinusOne+numMinusTwo;
numMinusTwo=numMinusOne;
numMinusOne=jumpNum;
}
return jumpNum;
}
}
5.[编程题]变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
求该青蛙跳上一个n级的台阶总共有多少种跳法。
解题思路:
把这道题当成算数题来看,可以找到规律,每多一层台阶的跳法是前一层台阶跳法的2倍
public class Solution {
public int JumpFloorII(int target) {
if(target==1||target==2){
return target;
}else if(target<1){return -1;}
else{
return JumpFloorII(target-1)*2;
}
}
}
显然好像有比这个更好的解决办法:
位移操作~,,来来让我们看看吧!
>>右移操作
x>>y
就是x除以2的y次方,取整数
<<左移操作
X<<y
就是x乘以2的y次方
通过算数的方法可以求出 跳法数量为2^(n-1)
public class Solution {
public int JumpFloorII(int target) {
int a=1;
return a<<(target-1);
}
}
6.[编程题]矩形覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
依旧是斐波那契数列
2*n的大矩形,和n个2*1的小矩形
其中target*2为大矩阵的大小
有以下几种情形:
1、target = 1大矩形为2*1,只有一种摆放方法,return1;
2、target = 2 大矩形为2*2,有两种摆放方法,return2;
3、target = n 分为两步考虑:
如果第一格竖着放,只占一个格,还剩n-1格 f(target-1)种方法
如果前两格横着放两个,占两个格,还剩n-2格 f(target-2)种方法
public class Solution {
public int RectCover(int target) {
if(target==0||target==1||target==2){
return target;
}else if(target<0){return -1;}
else{
return RectCover(target-1)+RectCover(target-2);
}
}
}