数组(算法题)(1)

package com.qyc.arrays;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.junit.Test;
import org.omg.CORBA.PUBLIC_MEMBER;

public class Arrays_operation {
	// 1.寻找数组中的最大值与最小值

	@Test
	public void maxMin() {
		int a[] = { 7, 3, 19, 40, 4, 7, 1 };
		int max = a[0];
		int min = a[0];
		for (int i = 1; i < a.length; i++) {
			if (a[i] > max) {
				max = a[i];
			}
			if (a[i] < min) {
				min = a[i];
			}
		}
		System.out.println("max:" + max + "\n" + "min:" + min);
	}

	// 2.找数组中第二大的数
	@Test
	public void findSecMax() {
		int a[] = { 1, -1, 4, 8, -4, 7, 8, -5 };
		int max = a[0];
		int secmax = 0;
		for (int i = 1; i < a.length; i++) {
			if (a[i] > max) {
				secmax = max;
				max = a[i];
			} else {
				if (a[i] > secmax && a[i] != max) {
					secmax = a[i];
				}
			}
		}
		System.out.println("max:" + max + "\n" + "secmax:" + secmax);
	}

	// 3.求最大子数组之和
	// (1)重复利用已经算出的子数组之和
	@Test
	public void maxSubArray() {
		int a[] = { 1, -2, 4, 8, -4, 7, -1, -5 };
		int max = Integer.MIN_VALUE;
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int sum = 0;
			for (int j = i; j < n; j++) {
				sum += a[j];
				if (sum > max) {
					max = sum;
				}
			}
		}
		System.out.println(max);

	}

	// (2)动态规划
	@Test
	public void dynamicProgramming() {
		int a[] = { 1, -2, 4, 8, -4, 7, -1, -5 };
		int n = a.length;
		int end[] = new int[n];
		int max[] = new int[n];
		end[0] = a[0];
		max[0] = a[0];
		end[n - 1] = a[n - 1];
		max[n - 1] = a[n - 1];
		int i = 1;
		for (; i < n; ++i) {
			end[i] = end[i - 1] + a[i] > a[i] ? end[i - 1] + a[i] : a[i];
			max[i] = end[i] > max[i - 1] ? end[i] : max[i - 1];
		}
		System.out.println(max[i - 1]);
	}

	// (3)优化动态规划
	@Test
	public void dynamicProgramming_Optimize() {
		int a[] = { 1, -2, 4, 8, -4, 7, -1, -5 };
		int n = a.length;
		int end;
		int max;
		end = a[0];
		max = a[0];
		for (int i = 1; i < n; ++i) {
			end = end + a[i] > a[i] ? end + a[i] : a[i];
			max = end > max ? end : max;
		}
		System.out.println(max);
	}
	//(4)求最大子串位置
	@Test
	public void location() {
		int a[] = { 1, -2, 4, 8, -4, 7, -1, -5 };
		int n = a.length;
		int end;
		int max;
		end = a[0];
		max = a[0];
		int star = 1;
		int End = 1;
		for (int i = 1; i < n; i++) {
			if(end + a[i] > a[i]){
				end = end + a[i];
				
			}else{
				end = a[i];
				star = i;
			}
			if(end > max){
				max = end;
				End = i;
			}
		}
		System.out.println(max+" "+star+" "+End);
	}
	
	
	//找出数组中重复元素最多的数(使用Map映射表)
	/*
	 HashMap工作原理:内部用数组实现,只是数组比较特殊,数组里存储的元素是一个实体,实体主要包含,key,value,
	  以及一个指向自身的next的指针。hashMap是基于hash实现的。
	 1. 当我们进行put操作时根据传递的key值得到他的hashcode,然后用hashcode与数组的长度进行取模运算,得到一个int值,
	  那么这个整型值就是在数组的位置。
	 2.进行get是,通过get方法获取指定的key值,会根据指定的key值算出hash值,根据hash值获取数组下标对应的实体,然后判断实体里的key值
	  和hash值,是否要与查找相同,如果相同返回value,否则遍历该链表直到找到这个值为止,
	  如果值不存在,则返回空,hash之所以在每一个数组元素存储的是一个链表是为了解决hash冲突问题。当俩个对象的hash值相等时,一个为止肯定放不下俩个值,
	 于是hash采用链表来解决这种冲突,俩个相同的值会形成一个新的链表。
	*/
	@Test
	public void findMostFrequentInArray() {
		int[] a = {1,5,4,3,4,4,5,4,5,5,6,6,6,6,6};
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		for(int i = 0;i<a.length;i++){
			if(map.containsKey(a[i])){
				map.put(a[i], map.get(a[i])+1);
			}else{
				map.put(a[i], 1);
			}
		}
		int temp = 0;
		int num = 0;
		Iterator iterator = map.entrySet().iterator();
		while(iterator.hasNext()){
			Map.Entry entry = (Map.Entry)iterator.next();
			
			int nums = (int) entry.getValue();
			if(nums>num){
				temp = (int) entry.getKey();
				num = nums;
			}
		}
		System.out.println("temp"+temp+"  nums="+num);
	}
	
	//求数组中俩俩相加等于20的组合种数
	@Test
	public void findSum() {
		int a[] = {1,7,17,2,6,3,14};
		for(int i = 0;i<a.length-1;i++){
			for(int j = 0;j<a.length-i-1;j++){
				if(a[j]>a[j+1]){
					int temp = a[j];
					a[j] = a[j+1];
					a[j+1]= temp;
				}
			}
		}
		int begin = 0;
		int end = a.length-1;
		while(begin<end){
			if(a[begin]+a[end]<20){
				begin++;
			}else if(a[begin]+a[end]>20){
				end--;
			}else{
				System.out.println(a[begin]+"  "+a[end]);
				begin++;
				end--;
			}
		}
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值