1.
要求输入一组英文字符串数组,让这个字符串数组中前面一个元素的最后一个 字母和下一个元素的首位上的字母相等,并且每个元素的长度大于等于2且小于等于100
public static void
main(String[] a )
{
Two t = new
Two();
System.out.println(t.s());
}
public int
s(){
//
String[] args={"abcd","def","fgr","rtg"};
String[]
args={"abcd","def","A","rtg"};
for (int i=0;i
boolean
b1 =args[i].matches("[a-z]+");
boolean
b2 = args[i].length()>=2 ;
boolean
b3 = args[i].length()<=100 ;
if(b1&&b2&&b3){
char c1 =
args[i].charAt(args[i].length()-1);
char c2 =
args[i+1].charAt(0);
if(c1==c2){
b=
Two.show1();
}else{
b=
Two.show2();
break;
}
}else{
b=
Two.show2();
break;
}
}
if(b==true){
return
1;
}else{
return
-1;
}
}
public static boolean show1(){
return true;
}
public static boolean show2(){
return false;
}
2、快速找出一个数组中的最大数、第二大数。
思路:如果当前元素大于最大数 max,则让第二大数等于原来的最大数
max,再把当前元素的值赋给
max。如果当前的元素大于等于第二大数secondMax的值而小于最大数max的值,则要把当前元素的值赋给
secondMax。
public
static void main(String[] a1 )
{
Two t = new
Two();
int[]
a={12,233,4232,2,23,1,234};
t.compare(a);
}
public void
compare(int[] a){
int max =
a[0];
int max2 =
a[a.length-1];
for(int
i=0;i
if(a[i]>max){
max2 =
max;
max =
a[i];
}else
if(a[i]>max2 && a[i]
max2 =
a[i];
}
}
System.out.println("这个数组最大的是:"+max);
System.out.println("这个数组第二大的是:"+max2);
}
法二:
public
static void main(String[] a1 )
{
Two t = new
Two();
int[]
a={12,233,4232,2,23,1,234};
java.util.Arrays.sort(a);
System.out.println(java.util.Arrays.toString(a)
);//输出数组可以不用遍历
System.out.println("这个数组最大的是:"+a[a.length-1]);
System.out.println("这个数组第二大的是:"+a[a.length-2]);
}
3、试着用最小的比较次数去寻找数组中的最大值和最小值。
解法一:扫描一次数组找出最大值;再扫描一次数组找出最小值。比较次数2N-2
解法二:将数组中相邻的两个数分在一组,每次比较两个相邻的数,将较大值交换至这两个数的左边,较小值放于右边。对大者组扫描一次找出最大值,对小者组扫描一次找出最小值。
比较1.5N-2次,但需要改变数组结构
解法三:
每次比较相邻两个数,较大者与MAX比较,较小者与MIN比较,找出最大值和最小值。
方法如下:先将一对元素互相进行比较,然后把最小值跟当前最小值进行比较,把最大值跟当前最大值进行比较。因此每两个元素需要3次比较。如果n为奇数,那么比较的次数是3*(n/2)次比较。如果n为偶数,那么比较的次数是3n/2-2次比较。因此,不管是n是奇数还是偶数,比较的次数至多是1.5n :
public
static void main(String[] a1 )
{
Two t = new
Two();
int[]
a={12,233,4232,-12,23,1,234};
t.compare(a);
}
public
void compare(int[] a){
int max =
a[0];
int min =
a[a.length-1];
for(int
i=0;i
if(a[i]>a[i+1]){
if(a[i]>max){
max =
a[i];
}
if(a[i+1]
min =
a[i+1];
}
}
}
System.out.println("这个数组的最大值是:"+max);
System.out.println("这个数组的最小值是:"+min);
}
4、重排问题
给定含有n个元素的整型数组a,其中包括0元素和非0元素,对数组进行排序,要求:
1、排序后所有0元素在前,所有非零元素在后,且非零元素排序前后相对位置不变
2、不能使用额外存储空间
例子如下
输入 0、3、0、2、1、0、0
输出 0、0、0、0、3、2、1
分析: 如果当前位置上为0,他前面的不为0 ,则交换
public
static void main(String[] a1 )
{
int[] a ={0,1,2,0,3,0,2,0,0};
for(int j=0;j
for(int i=1;i
if( a[i]== 0&& a[i-1]!=0){
a[i]=a[i-1];
a[i-1]=0;
}
}
}
System.out.println(java.util.Arrays.toString(a));
}
5、找出绝对值最小的元素
给定一个有序整数序列(非递减序),可能包含负数,找出其中绝对值最小的元素,比如给定序列 -5、-3、-1、2、8 则返回1。
分析:由于给定序列是有序的,而这又是搜索问题,所以首先想到二分搜索法,只不过这个二分法比普通的二分法稍微麻烦点,可以分为下面几种情况
如果给定的序列中所有的数都是正数,那么数组的第一个元素即是结果。
如果给定的序列中所有的数都是负数,那么数组的最后一个元素即是结果。
如果给定的序列中既有正数又有负数,那么绝对值的最小值一定出现在正数和负数的分界处。
为什么?因为对于负数序列来说,右侧的数字比左侧的数字绝对值小,如上面的-5、-3、-1,而对于整整数来说,左边的数字绝对值小,比如上面的2、8,将这个思想用于二分搜索,可先判断中间元素和两侧元素的符号,然后根据符号决定搜索区间,逐步缩小搜索区间,直到只剩下两个元素。
单独设置一个函数用来判断两个整数的符号是否相同
public
static void main(String[] a1 )
{
int[] a ={-5,-3,12,-1,90,2,9};
int[] b = new int[a.length];
for(int
i=0;i
b[i] = Math.abs(a[i]);
}
int minAbs
= b[0];
for(int
i=0;i
if(b[i]
minAbs =
b[i];
}
}
System.out.println(java.util.Arrays.toString(a));
System.out.println(java.util.Arrays.toString(b));
System.out.println(minAbs);
}
6、从长度为n的数组(元素互不相同)中任意选择m个数的所有组合。
7、从长度为n的数组(元素有可能相同)中任意选择m个数的所有组合。
先对数组进行排序,然后设置一个标记pre,记录前一个选择的数字,然后进行比较。
import
java.util.*;
public
class Two
{
public
static void main(String[] a1 )
{
String[] data = {"1", "2", "2","3", "4", "5"};
int num = 3;
List> result = parade(Arrays.asList(data), num);
for (List x : result) {
System.out.println(x);
}
System.out.printf("total:%s\n", result.size());
}
public static List> parade(List data, int num) {
List> result = new ArrayList>();
if (num == 1) { //只排一个元素的时候(递归结束条件)
for (String s : data) {
List l = new ArrayList();
l.add(s);
result.add(l); //每个元素分别保存到结果集
}
return result; //并返回结果集
}
for (int i=0; i1,即排多个元素的时候,循环
List list = new ArrayList(data);
list.remove(i);
//去掉当前循环的元素作为下次递归的参数,即剩余的元素做递归
List> sub = parade(list, num-1); //递归调用
for (List l : sub) { //然后循环递归得到的结果
l.add(0, data.get(i)); //把当前元素排在每个结果的前面
result.add(l);
//并保存到结果集
}
}
return result; //最后返回结果集
}
}
8、三色旗排序问题
假设有一根绳子,上面有一些红、白、蓝色的旗子。起初旗子的顺序是任意的,现在要求用最少的次数移动这些旗子,使得它们按照蓝、白、红的顺序排列。注意只能在绳子上操作,并且一次只能调换两个旗子。
public
class Two {
public static final char BLUE = 'b';
public static final char RED = 'r';
public static final char WHITE = 'w';
public static final char[] color = { 'r', 'w', 'b', 'w', 'w', 'b',
'r', 'b', 'w', 'r' };
// 交换彩旗的方法
public static void SWAP(int x, int y) {
char temp = color[x];
color[x] = color[y];
color[y] = temp;
}
public static void main(String[] a1) {
int bFlag = 0;
int wFlag = 0;
int rFlag = color.length - 1;
for (int i = 0; i < color.length; i++) {
System.out.print(color[i]);
}
System.out.println();
while (wFlag <= rFlag) {
if (color[wFlag] == WHITE) {
wFlag++;
} else if (color[wFlag] == BLUE) {
SWAP(bFlag, wFlag);
bFlag++;
wFlag++;
} else {
while (wFlag < rFlag && color[rFlag] == RED)
{
rFlag--;
}
SWAP(rFlag, wFlag);
rFlag--;
}
}
for (int i = 0; i < color.length; i++) {
System.out.print(color[i]);
}
System.out.println();
}}
9、一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它。能否只用一个额外数组和少量其它空间实现。
分析:最原始的方法是检查每一个数 array[i] ,看是否左边的数都小于等于它,右边的数都大于等于它。这样做的话,要找出所有这样的数,时间复杂度为O(N^2)。
其实可以有更简单的方法,我们使用额外数组,比如rightMin[],来帮我们记录原始数组array[i]右边(包括自己)的最小值。假如原始数组为:
array[] = {7, 10, 2, 6, 19, 22,
32},
那么rightMin[] = {2, 2, 2,
6, 19, 22, 32}. 也就是说,7右边的最小值为2, 2右边的最小值也是2。
有了这样一个额外数组,当我们从头开始遍历原始数组时,我们保存一个当前最大值 max,
如果当前最大值刚好等于rightMin[i],
那么这个最大值一定满足条件,还是刚才的例子。
第一个值是7,最大值也是7,因为7 不等于 2,
继续,
第二个值是10,最大值变成了10,但是10也不等于2,继续,
第三个值是2,最大值是10,但是10也不等于2,继续,
第四个值是6,最大值是10,但是10不等于6,继续,
第五个值是19,最大值变成了19,而且19也等于当前rightMin[4] = 19, 所以,满足条件。如此继续下去,后面的几个都满足。
public
class Two {
public static void main(String s[]) {
try {
smallLarge(new int[] { 7, 10, 2, 6, 19, 22, 32 });
} catch (Exception e) {
e.printStackTrace();
}
}
public static void smallLarge(int[] array) throws Exception
{
if (array == null || array.length < 1) {
throw new Exception("the array is null or the array has no
element!");
}
int[] rightMin = new int[array.length];
rightMin[array.length - 1] = array[array.length - 1];
for (int i = array.length - 2; i >= 0; i--) {
if (array[i] < rightMin[i + 1]) {
rightMin[i] = array[i];
} else {
rightMin[i] = rightMin[i + 1];
}
}
int leftMax = Integer.MIN_VALUE;
for (int i = 0; i < array.length; i++) {
if (leftMax <= array[i]) {
leftMax = array[i];
if (leftMax == rightMin[i]) {
System.out.println(leftMax);
}
}
}
}
}
10、整数的拆分问题
如,对于正整数n=6,可以拆分为:
6
5+1
4+2
4+1+1
3+3
3+2+1
3+1+1+1
2+2+2
2+2+1+1
2+1+1+1+1
1+1+1+1+1+1
现在的问题是,对于给定的正整数n,程序输出该整数的拆分种类数
public
class Two {
public static int splitInteger(int sum,
int max, int[] data, int index) {
if (max > sum) max = sum;
if (sum < 1 || max < 1) return 0;
if (sum == 1 || max == 1) {
if (sum == 1) {
data[index] = sum;
print(data, index+1);
} else {
for (int i = 0; i < sum; i++) {
data[index++]
= max;
}
print(data, index);
}
return 1;
}
if (sum == max) {
data[index] = max;
print(data, index+1);
return 1 + splitInteger(sum, max-1, data, index);
} else if (sum > max) {
data[index] = max;
//一定注意这里的先后顺序
return splitInteger(sum-max, max, data, index+1) +
splitInteger(sum, max-1, data, index);
} else {
//sum < max
return splitInteger(sum, sum, data, index);
}
}
public
static void print(int[] data, int index) { //打印数组
for (int i = 0; i < index -1; i++) {
System.out.print(data[i] + "+");
}
System.out.println(data[index-1]);
}
*
正整数加法不同分解的个数:最大值为max,和为sum的加法个数
递归形式: f(sum, max) =
f(sum-max, max) + f(sum, max-1);
public static int count(int sum, int max) {
if (sum < 1 || max < 1) return 0;
else if (sum == 1 || max == 1){
return 1;
} else if (sum < max) {
return count(sum,sum);
} else if (sum == max) {
return 1+count(sum, sum-1);
} else {
return count(sum, max-1)+count(sum-max,max);
}
}
public static void main(String[] args) {
int n = 4;
int[] data = new int[n];
System.out.println("正整数\'" + n + "\'可以分解为如下不同的加法形式:");
System.out.println("正整数\'" + n + " \'加法分解个数为:\t" + splitInteger(n,n,data,0));
n = 100;
System.out.println("正整数\'" + n + "\'加法分解个数为(包含本身):\t" + count(n,n));
System.out.println("正整数\'" + n + "\'加法分解个数为(不包含本身):\t" + count(n,n-1));
}
}
11、在数组中寻找和为给定值的组合
public class Two
{
static int[] arr ={1, 5, 9, 3, 4, 7, 6, 2, 8};
static int maxIndex = arr.length - 1;// 索引最大值
static int sum = 11;// 求两个数的和等于的值
public static void main(String[] args)
{
find1(arr);
}
//
1.所有数字两两组合,计算;时间复杂度O(n*n)
//
2.先把数组排序,然后利用二分查找在数组中查找,判断sum-arr[i]是否在数组中;时间复杂度O(n*longn)
//
3.先对数组排序i=0,j=n-1,如果:sum如果:sum
//
如果有序,直接两个指针两端扫描,时间O(N);如果无序,先排序后两端扫描,时间O(N*logN+N)=O(N*logN),空间始终都为O(1)
static void find1(int[]
arr) {
Arrays.sort(arr);// 对数组排序
for (int i = 0, j = maxIndex; i < j;)
{
if (arr[i] + arr[j] == sum)
{
System.out.println(sum + " = " + arr[i] + " + " +
arr[j]);
i++;//
没有这一句死循环
}
else if (arr[i] + arr[j] < sum)
{
i++;
}
else
{
j--;
}
}
}}
12、求数组中两个元素差的最大值
import
java.util.*;
public
class Two {
public static void main(String[] a1) {
Listresult = new ArrayList();
int[] aa =
{12,2,34,54,65,3,2,5,-12,4,0};
for(int i
=0;i
for(int j
=0; j
int cha =
aa[i]-aa[j];
int cha2 =
aa[j]-aa[i];
result.add(cha);
result.add(cha2);
}
}
int min =
result.get(0);
for(int i
=0;i
if(result.get(i)<
min){
min =
result.get(i);
}
}
System.out.println("两个元素的差为:");
for(Integer
x : result){
System.out.print(x+"
");
}
System.out.println();
System.out.println("两个元素的差总共有"+result.size()+"个");
System.out.println("两个元素的差的最小值时:"+min);
}
}
13、输入一个正数
n,输出所有和为
n 连续正数序列。
例如输入 15,由于
1+2+3+4+5=4+5+6=7+8=15,所以输出
3 个连续序列 1-5、4-6 和 7-8。
package
com.tankxiancheng;
public
class Two {
public
static void
getAns(int n){
int beg=1;
int sum=1;
int cur=1;
while(beg<=n/2+1){
if(sum==n){
for(int k=beg;k<=cur;k++){
if(k == cur){
System.out.print(k+"=15");
}else{
System.out.print(k+"+");
}
}
System.out.println();
sum=sum-beg;
beg++;
cur++;
sum+=cur;
}
if(sum>n){
sum=sum-beg;
beg++;
}else
{
cur++;
sum+=cur;
}
}
}
public
static void main(String[] args) {
getAns(15);
}
}