笔试题之算法初识
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.先对字符串数组排序,然后对其后元素两两比较,获取到重复的数值,看代码把,注释好清晰咯
第一题就这么完咯,其实第一题还有一种解法,如果你对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. 不得将链表转化为其他类型数据结构再进行交换,如数组等
第二题一看过去就知道考我们数据结构咯。这个简单,自认为数据结构学的还不错。直接上代码
注释都写的非常清楚咯,至于为什么标这么清楚,这是笔试题要求的没办法,
笔试题就写完咯,感觉写的并不是很好,希望针对这两题有更快速更简便算法的人给点意见,让我在长长经验。
请看题目吧
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; } } }
注释都写的非常清楚咯,至于为什么标这么清楚,这是笔试题要求的没办法,
笔试题就写完咯,感觉写的并不是很好,希望针对这两题有更快速更简便算法的人给点意见,让我在长长经验。
相关文章推荐
- NYOJ 17 单调递增最长子序列
- windows下VisualStudio和QtCreator搭建Qt开发环境
- php日记——使用mysqli
- 重排算法与分区算法
- Android 之Please ensure that adb is correctly located at 的问题解决方法
- OpenStack Hacker养成指南
- spring MVC解决中文传参乱码问题
- Android Studio使用--Android Device Monitor doesnt open
- 第2周项目4—用循环求(2)
- PrintWriter类 讲解
- iOS tableView 下拉列表的设计
- redis-master/slave模式
- 测试测试
- spring aop 与 aspectj
- 析构函数到底都做了什么
- php MVC原理
- 值类型和引用类型
- 第二周项目-小试循环
- iOS登录界面和注册界面
- 构建之法阅读笔记02