1. 内存中有一个长数组,条目数为10万,数组单元为结构体struct array,sizeof(struct array)为512字节。结构有一int型成员变量weight。现需要取得按weight值从大到小排序的前500个数组单元,请实现算法,要求效率尽可能高。
package org.jyjiao.test1;
//Struct 元素类
class Struct{
private int weight;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
//堆操作
class Heap{
Struct[] items;
int itemsLen; //堆大小
int lastIndex; //最后一个元素的下标
public Heap(Struct[] items){
this.items=items;
this.itemsLen=items.length;
this.lastIndex=this.itemsLen-1;
}
//创建最大堆
public void createHeap(){
if(itemsLen>0){
for(int i=itemsLen/2-1;i>=0;i--){
siftDown(i); //注意参数
}
}else{
System.out.println("array is null");
}
}
//取得堆顶元素,并重新调整堆
public Struct getMax(){
Struct ret=items[0];
items[0]=items[lastIndex];
lastIndex--;
siftDown(0);
return ret;
}
//向下筛
void siftDown(int i){ //核心算法
int childIndex;
while((2*i+1)<=lastIndex ){
childIndex=2*i+1;
if((2*i+2)<=lastIndex && items[2*i+1].getWeight()<items[2*i+2].getWeight()){
childIndex=2*i+2;
}
if(items[i].getWeight()<items[childIndex].getWeight()){
Struct tmp=items[i];
items[i]=items[childIndex];
items[childIndex]=tmp;
i=childIndex;
}else{
break;
}
}//while
}
}
//测试代码
public class Max500 {
public static void main(String[] args){
Struct[] array=new Struct[10];
for(int i=0;i<10;i++){
array[i]=new Struct(); //本句不能缺少,必须初始化数组对象!
array[i].setWeight((int)(Math.random()*50)); //注意用set,不要用赋值语句
System.out.print(array[i].getWeight()+" ");
}
System.out.println("\n");
Heap heap=new Heap(array);
heap.createHeap();
for(int i=0;i<5;i++){
Struct tmp=heap.getMax();
System.out.print(tmp.getWeight()+" ");
}
}
}
算法效率: O(n)
2. 现有两个文件,
a)数据文件A,格式为:关键词、IP地址、时间,记录条数为1000万左右,该文件是无序排列的。
b)数据文件B是关键词ID到关键词的对应表文件,格式为:ID、关键词,记录条数在100万左右,也是无序排列的。该对应表中的记录是一一对应的,不存在ID或者关键词重复的情况。
要求将数据文件A对应的关键词替换为B中的ID,生成新的数据文件C,数据文件C的格式为:关键词ID、IP地址、时间。
请设计一个程序,实现上述功能,并分析时间复杂度和空间复杂度。运行程序所使用的服务器的内存为1G,硬盘足够大。(至少要给出关键算法和设计思路)
package org.jyjiao.test1;
import java.io.*;
import java.util.*;
public class ReplaceKeyWord {
String fileA, fileB, fileC;
HashMap<String,Integer> map;
public ReplaceKeyWord(String fileA, String fileB, String fileC) {
this.fileA = fileA;
this.fileB = fileB;
this.fileC = fileC;
map = new HashMap<String,Integer>();
}
public void replace() {
try {
BufferedReader brA = new BufferedReader(new FileReader(fileA));
BufferedReader brB = new BufferedReader(new FileReader(fileB));
BufferedWriter bwC = new BufferedWriter(new FileWriter(fileC));
// iniciate hashmap (时间复杂度:O(1M),空间复杂度:O(1M))
String str;
while ((str = brB.readLine()) != null) {
str.trim();
String[] tmpB = new String[2];
tmpB = str.split("、");
map.put(tmpB[1],new Integer(tmpB[0]));
}
// input fileC (时间复杂度:O(10M), 空间复杂度:O(1))
while ((str = brA.readLine()) != null) {
str.trim();
String[] tmpA=str.split("、");
String key=tmpA[0];
if(map.containsKey(key)){
Integer id=map.get(key);
str=id+"、"+tmpA[1]+"、"+tmpA[2];
bwC.write(str);
bwC.newLine();
}
}
brA.close();
brB.close();
bwC.flush();
bwC.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
}
}
public static void main(String[] args) {
String fileA="D:\\fileA.txt";
String fileB="D:\\fileB.txt";
String fileC="D:\\fileC.txt";
ReplaceKeyWord rk=new ReplaceKeyWord(fileA,fileB,fileC);
rk.replace();
}
}
时间复杂度:O(len(fileA)) , 空间复杂度:O(len(fileB))
3. 对一个数组S,求其中满足要求的最大元素C。要求C满足等式C=A*B,其中A、B也是数组S中的元素。请用能想到的最优算法,分析时间和空间复杂度。(用语言描述算法,不用写程序)
注:这个题我当时做的方法在时间上要用o(n^3),事后想出了个o(n^2 logn)的方法。不知有没有更好的方法。
package org.jyjiao.test1;
import java.util.*;
public class MaxProduct {
public static void main(String[] args){
int[] S={2,3,6,18,36,216,12,108};
int C=0;;
HashSet<Integer> set=new HashSet<Integer>();
for(int i=0;i<S.length;i++){
set.add(new Integer(S[i]));
}
for(int i=0;i<S.length;i++){
for(int j=i+1;j<S.length;j++){
int tmp=S[i]*S[j];
if(set.contains(new Integer(tmp))){
if(tmp>C){
C=tmp;
}
}
}
}
System.out.println("max product is:"+C);
}
}
5. 一个整数数列,元素取值可能是1-N(N是较大的正整数)中的任意一个数,相同数值不会重复出现。设计一个算法,找出数列中符合条件的的数对的个数,满足数对中两个数的和等于N+1。
复杂度最好是O(n)
6.有个整数数列,如何求绝对数和最大的连续字符串,