使用Java,采用两种方法对50个随机整数求和

问题描述:

设计一个链表,插入50个随机整数。每次从链表中找出两个最小整数,将这两个整数从链表中移除,再将这两个整数之和作为新的数字加入链表,直至链表中只有一个数字

将链表换成数组,执行上述过程,比较数组和链表的差异。


问题分析:

1. 由于在整个过程中,链表需要变动,所以采用LinkedList效率会比较好。

2. 但数组就不一样了,数组是顺序存储的,一旦移除某个元素,这个元素后面的元素都要往前推,而插入一个元素的话,其后的元素都要往后以一个位置。

    这样做的话,效率会非常低。

问题解决:

对于数组,采用如下小技巧提高效率:

 假设最小的两个数为A和B,它们的和为C,数组的第一个位置的元素为D

把C的值赋给A,交换B和D。

这样,出了数组第一个位置的元素,其他都是我们需要的数据。

就这样循环,直到数组是剩下一个元素为止。


代码如下:

package com.test.ly;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;

public class TestList {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		List<Integer> lst = new LinkedList<Integer>();
		int[] arr = new int[50];
		
		generateData(lst,50);
		generateData(arr,arr.length);
		
		System.out.println("sum from List is :"+ getSum(lst));
		System.out.println("sum from Arr is :"+ getSum(arr));
	}


	@SuppressWarnings("unchecked")
	private static Object generateData(Object obj,int size) {
		
		if(obj == null)
			return null;
		
		Random rdm = new Random();
		
		if(obj instanceof LinkedList){
			for(int i = 0;i<size;i++){
				((LinkedList<Integer>) obj).add(rdm.nextInt());
			}
		}else if(obj instanceof int[]){
			for(int i=0;i<size;i++){
				((int[]) obj)[i] = rdm.nextInt();
			}
		}
		return obj;
		
	}

	@SuppressWarnings({ "unchecked" })
	private static int getSum(Object obj) {
		
		List<Integer>  smallest = null;
		if(obj instanceof LinkedList){
			LinkedList<Integer> sumList = (LinkedList<Integer>) obj;
			if(sumList.isEmpty()){
				return 0;
			}
			
			while(sumList.size() != 1){
				smallest = find(sumList,0);
				sumList.removeAll(smallest);
				sumList.add(smallest.get(0)+smallest.get(1));
			}
			return sumList.get(0);
		}
		
		
	
		
		/**
		 * need to improve
		 */
		if(obj instanceof int[]){
			int[] sumArr = (int[]) obj;
			if(sumArr == null || sumArr.length ==0){
				return 0;
			}
			
			int startIndex = 0;
			while( (sumArr.length-startIndex) != 1){  
				smallest = find(sumArr,startIndex);
				
				
				/**
				 * replace 
				 * 
				 * replace the smallest one with sumArr[startIndex]
				 * replace the second smallest one with sumArr[startIndex+1]
				 * and the startIndex++
				 * 
				 * with the above method, you can ellipsis the trimming array loops,
				 * and it also improve the  efficiency
				 */
				int tempSum = sumArr[smallest.get(0)] + sumArr[smallest.get(1)];
				sumArr[smallest.get(0)] = sumArr[startIndex];
				sumArr[smallest.get(1)] = sumArr[startIndex+1];
				sumArr[startIndex+1] = tempSum;
				
				startIndex ++;
				
				
				
//				for(int i = smallest.get(0);i<sumArr.length-1;i++){
//					sumArr[i]=sumArr[i+1];
//				}
//				for(int i = smallest.get(1);i<sumArr.length-1;i++){
//					sumArr[i]=sumArr[i+1];
//				}
			}
			return sumArr[sumArr.length-1];
		}
		
		return 0;
		
	}

	@SuppressWarnings("unchecked")
	private static List<Integer> find(Object obj,int startIndex) {
		
		List<Integer> resultList = new LinkedList<Integer>();
		int smallest = 0;
		int secondSmallest = 0;
		
		if(obj == null){
			resultList.add(smallest);
			resultList.add(secondSmallest);
			return resultList;
		}
		
		if(obj instanceof LinkedList){
			LinkedList<Integer> lst =  (LinkedList<Integer>) obj;
			smallest= lst.get(0);
			secondSmallest = lst.get(1);
			
			
			if(lst.size()>2)
			for(int index =2;index< lst.size();index++){
				int current = lst.get(index);
				if(current < smallest){
					smallest = current;
				}else if( current <secondSmallest){
					secondSmallest = current;
				}
			}
		}
		
		/**
		 * in this section, we use the index
		 */
		if(obj instanceof int[]){
			int[] arr = (int[]) obj;
			smallest= startIndex;
			secondSmallest = startIndex+1;
			
			if( (arr.length-startIndex) > 2)
			for(int index =startIndex+2;index< arr.length;index++){
				int current = arr[index];
				if(current < arr[smallest]){
					smallest = index;
				}else if( current <arr[secondSmallest]){
					secondSmallest = index;
				}
			}
		}
		
		
		resultList.add(smallest);
		resultList.add(secondSmallest);
		
		return resultList;
		
	}
	



}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值