java 数组 题_(第22讲)java数组的一些编程题

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);

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值