您的位置:首页 > 其它

笔试题之算法初识

2016-03-10 18:37 405 查看
这段时间一直沉浸在自己的工作和学习中,一个电话打破我的宁静的生活,竟然是通知我笔试的。还发来一套笔试题,打开一看,两道题就,都是我喜欢的算法题,于是便开始准备解决这两道题,使生活回归宁静。

请看题目吧

1. 找出n个字符串中出现次数最多的字符串。

C/C++:

char* find(char **data,int n);

Java:

String find(String data[]);

说明:

data是字符串数组,n是数组中字符串的个数,返回值为出现次数最多的字符串。

若结果有多个,返回任意一个即可

不得使用任何库函数/API,如需使用类似功能, 请自行实现

算法效率尽可能高,尽量少的使用内存空间

必须要有代码注释和算法说明。

例如:data里面的数据是{“paper”,”cup”,”book”,”cup”,”pen”,”book”}。n = 6。返回结果为”cup”或”book”。

这题坑的我太惨,刚开始认为可以将paper转换成数字,然后该数字相当于数组的下标,通过数组值来知道重复最多的是哪个,结果想想又不可能,除非数组开的特别大。

2.又想了一下字典序算法,所谓的字典序,就是先查首字母相同的,在首字母相同的请看然后在查第二个,依次下去,直到查到最后一个字母位置,思路有了,但是我并不会实现啊。于是有了第三种方法

3.先对字符串数组排序,然后对其后元素两两比较,获取到重复的数值,看代码把,注释好清晰咯

public class Test1 {

/**
* 比较两个字符串大小
* @param str
* @param str2
* @return
*/
public int check(String str,String str2){
return str.compareTo(str2);
}

/**
* 快速排序算法
* 通过一躺排序将要排序的数据分割成独立的两部分,
* 其中一部分的所有数据都比另外一不部分的所有数据都要小,
* 然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,
* 以此达到整个数据变成有序序列。
* @param str
* @param begin
* @param end
*/
public void fast_sort(String[] str,int begin,int end)

{

//如果左节点小于右节点
if(begin<end)

{

int i =begin,j=end;
String key = str[begin];

while(i<j)

{
//从右往左遍历知道出现右边比左边小的或者开始节点等于末尾节点
while(i<j&&(check(str[j],key)>=0)) j--;

//交换两个位置
str[i]=str[j];
//从左往右遍历寻找左边比有点大的节点
while(i<j&&(check(str[i],key)<=0)) i++;
//交换两个位置
str[j]=str[i];

}

//记录本次排序关键数据
str[i]=key;

//递归左半部分排序
fast_sort(str,begin,i-1);

//递归右半部分排序
fast_sort(str,i+1,end);

}

}

public String find(String data[]){
/**设置目前的重复次数*/
int max=1;
/**设置目前重复最多的字符串**/
String maxStr = null;
/**快速排序**/
fast_sort(data, 0, data.length-1);

//获得排序后的字符串,对其后面的元素进行比较,算出该字符串重复次数
for(int i=0;i<data.length;i++){
//重复次数为1
int count=1;
//与之后的判断
for(int j=i+1;j<data.length;j++){
//若相等则重复
if(data[j].equals(data[i]))
{
//次数++
count++;
//次数大于最大的
if(count>max){
//把重复次数赋值给最大值并且更新
max = count;
maxStr =data[j];

}
//如果有重复下次遍历数组就可以跳过这个
i=j;
}
else{
break;
}
}
}

return maxStr;

}

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int max=1;
String maxStr;
String[] str ={"paper","cup1","book","cup1","pen","book","cup1"};
maxStr ="paper";

Test1 test = new Test1();
//System.out.println(test.find(str));
maxStr = test.find(str);

System.out.println(maxStr);

}

}


第一题就这么完咯,其实第一题还有一种解法,如果你对java的hashmap熟悉的话,完全可以用hashmap去实现。

下面第二题

2.2.将链表中的所有元素为奇数的节点移到元素为偶数节点的前面,并保证奇数之间顺序不变,偶数之间顺序不变。

示例:

交换前链表的顺序 交换后链表的顺序

4→5→3→1→2 ==> 5→3→1→4→2

1 ==> 1 (链表仅含一个元素)

2→1 ==>1→2

==> (链表为空)

C/C++:

链表节点定义为:

struct node {

struct node *next;

int value;

};

struct node *swap(struct node *list);

Java:

链表节点定义为:

class Node {

public Node next;

public int value

}

Node swap(Node list)

注意点和要求如下:

1. swap函数要求对节点的指针/引用进行操作(不得创建任何新的链表节点)

2. 不得使用任何库函数/API,如需使用类似功能, 请自行实现

3. 不得将链表转化为其他类型数据结构再进行交换,如数组等

第二题一看过去就知道考我们数据结构咯。这个简单,自认为数据结构学的还不错。直接上代码

public class Test {

/**
* 奇数的节点移到元素为偶数节点的前面
* 1.先遍历链表,把偶数放到链表末尾去,直到遇到第一个奇数时停止
* 2.遇到第一个奇数时,把第一个奇数作为链表的头指针
* 3.继续遍历,遇到偶数直接放到链表末尾,奇数则放到上一个奇数的后面
* 4.链表所有元素都遍历完成,都开始链表末尾的值为偶数的进行调换位置
* @param list
* @return
*/
public Node swap(Node list){
if(list ==null){
System.out.println("链表为空");
return null;
}else if(list.next==null){
System.out.print("链表只有一个元素");
return list;
}
else{
/**指针移动的当前节点*/
Node now = list;
/**末尾指针*/
Node end = list;
/**指针移动的前一个节点*/
Node pre = null;
/**遍历找出末尾指针"*/
while (end.next != null)
end = end.next;
/**更新尾节点的位置,不断的存放接收的偶数元素。*/
Node end2 = end;
/** 将第一个奇数前的偶数放到链尾*/
while (now.value % 2 == 0 && now != end) {
end2.next = now;
now = now.next;
end2.next.next = null;
end2 = end2.next;
}
/** 元素是奇数*/
if (now.value % 2 != 0) {
/* 头结点为第一个奇数 */
list = now;
while (now != end) {
if ((now.value) % 2 != 0) {//奇数
pre = now;
now = now.next;
} else {
// 将pre指向后一个节点
pre.next = now.next;
now.next = null;
end2.next = now;// 将当前的偶数放到链尾
// 链尾后移
end2 = now;
// 继续判断
now = pre.next;
}
}
} else {
pre = now;
}

/** 末尾节点为偶数的特殊处理*/
if ((end.value) % 2 == 0) {
pre.next = end.next;
end.next = null;
end2.next = end;
}
return list;
}

}

public static void main(String[] args){

Node node1 = new Node(4);
Node node2 = new Node(5);
Node node3 = new Node(3);
Node node4 = new Node(1);
Node node5 = new Node(2);

node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
node5.next = null;

Test test = new Test();
Node node = test.swap(node1);

while(node!=null){
System.out.println(node.value+"");
node = node.next;
}
}

}


注释都写的非常清楚咯,至于为什么标这么清楚,这是笔试题要求的没办法,

笔试题就写完咯,感觉写的并不是很好,希望针对这两题有更快速更简便算法的人给点意见,让我在长长经验。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: