笔试题目练习

 1、一个单词单词字母交换,可得另一个单词,如army->mary,成为兄弟单词。提供一个单词,在字典中找到它的兄弟。描述数据结构和查询过程。评点同去年9月份的一道题,见此文第3题:http://blog.csdn.net/v_july_v/article/details/6803368

统计每个字母出现的次数

4、算法题1
一个url指向的页面里面有另一个url,最终有一个url指向之前出现过的url或空,这两种情形都定义为null。这样构成一个单链表。给两条这样单链表,判断里面是否存在同样的url。url以亿级计,资源不足以hash。

环?

5、算法题2

数组al[0,mid-1] 和 al[mid,num-1],都分别有序。将其merge成有序数组al[0,num-1],要求空间复杂度O(1)

插入排序


 1、删除字符串开始及末尾的空白符,并且把数组中间的多个空格(如果有)符转化为1个。

package com.duoduo.test;

public class StringFilterBlank {
	public static String filter(String a) {
		if (a == null || a.equals("")) {
			return a;
		}
		int N = a.length();
		int M = 0;
		char[] str = a.toCharArray();
		// step 1:统计去白后的字符串长度M
		int head = 0, tail = N - 1;
		while (head < N && str[head] == ' ') {
			head++;
		}
		while (tail >= 0 && str[tail] == ' ') {
			tail--;
		}
		for (int i = head; i <= tail; i++) {
			if (str[i] != ' ') {
				M++;
			} else if (str[i - 1] != ' ') {
				M++;
			}
		}
		if (M == 0) {
			return "";
		}
		// StdOut.println(M + " N: " + N + " head: " + head + " tail:" + tail);
		// 第二部 将空白除去
		int index = 0;

		while (index < M) {
			if (str[head] != ' ') {
				str[index++] = str[head++];
			} else {
				if (str[head - 1] != ' ') {
					str[index++] = str[head++];
				} else {
					head++;
				}
			}
		}

		return new String(str, 0, M);
	}

	public static void main(String args[]) {
		String[] TEST = new String[] { "abc dae bc ", "   abc dae bc ",
				"  abc  dae bc ", "  abc  dae   bc  ",
				"  a b c  d a e   b c  ", "", "  ", "         a", "b        " };
		for (String str : TEST) {
			System.out.println(filter(str));
		}
	}
}



找出两个单链表里交叉的第一个元素 

问题1:如何判断俩单链表(俩单链中均无环)是否交叉?
第一条链遍历至尾部,记此结点指针为p1;第二条链也遍历至尾部,此记结点指针为p2。则若此时p1与p2相等,俩单链交叉。

问题2:如果交叉,如何找到交叉点?
 若较长链表为head1。设两指针p1和p2分别对链表head1和head2从头遍历,步长均为1,让p1先移动nLen1 - nLen2步,再让p1和p2同时移动,则p1与p2相遇处即为交叉点处。


 9、字符串移动(字符串为*号和26个字母的任意组合,把*号都移动到最左侧,把字母移到最右侧并保持相对顺序不变),要求时间和空间复杂度最小

 从后向前遍历:

step 1、head记录星星的个数,如果为*则head++,否则a[i+head] = a[i]

step 2、将0~head位置赋值为*

http://blog.csdn.net/cxllyg/article/details/7985681

 10、时间复杂度为O(1),怎么找出一个栈里的最大元素   

辅助栈如图


2、线程和进程区别和联系。什么是“线程安全”

http://blog.csdn.net/gaopo_y/article/details/8080987

判断一个数字序列是BST(binary search tree)后序遍历的结果,现场写代码。

http://blog.csdn.net/hopeztm/article/category/1201028

2. 给出大小为N的数组,用最快的办法找出前M个大的数字

package com.duoduo.test;

import java.util.PriorityQueue;


public class QueueTest {
	public static void main(String args[]) {
		PriorityQueue<Integer> queue = new PriorityQueue<Integer>();
		int[] S = new int[] { 2, 1, 4, 5, 7, 11, 2, 1, 5, 7, 8, 3, 5, 7, 8, 3,
				2, 6 };
		int M = 10;
		int index = 0;
		while (index < M) {
			queue.add(S[index++]);
		}
		
		while (index < S.length) {
			if (queue.peek() < S[index]) {
				queue.remove();
				queue.add(S[index]);
			}
			index++;
		}
		System.out.println(queue);
		for (int i = 0; i < M; i++) {
			System.out.print(queue.poll() + " ");
		}
	}
}

活动安排问题(贪心算法)

http://blog.csdn.net/a9529lty/article/details/4042019


1. 数组乘积
输入: 一个长度为n的整数数组input
输出: 一个长度为n的数组result,满足result[i] = input数组中,除了input[i] 之外的所有数的乘积,不用考虑溢出
例如 input
{2, 3, 4, 5}
output:
{60, 40, 30, 24}
package com.duoduo.test;

public class MulLR {
	public static void main(String[] args) {
		int[] a = { 2, 3, 4, 5 };
		int N = a.length;
		int[] r = new int[N];
		int left, right;
		for (int i = 0; i < N; i++) {
			left = right = 1;
			for (int j = 0; j < i; j++) {
				left *= a[j];
			}
			for (int j = N - 1; j > i; j--) {
				right *= a[j];
			}
			r[i] = left * right;
		}
		for (int i = 0; i < N; i++) {
			System.out.print(r[i] + " ");
		}
	}
}


3. 朋友圈
假如已知有n个人和m对好友关系,如果两个人是直接或者间接有好友关系,则认为他们属于同一个朋友圈。写程序判断里面有多少朋友圈。
例如 
n = 5, m = 3  r = {(1,2), (2, 3), (4, 5)}  1 2 3 是一个朋友圈, 4 5 是一个朋友圈。
所以输出是2. 
无向图的连同问题(深度优先)
package com.duoduo.test;

import java.util.LinkedList;
import java.util.Queue;

public class GraphTest {
	private class Graph {
		private int V;
		private int E;
		private LinkedList<Integer>[] adj;

		public Graph(int V) {
			this.V = V;
			this.E = 0;
			adj = (LinkedList<Integer>[]) new LinkedList[V];
			for (int v = 0; v < V; v++) {
				adj[v] = new LinkedList<Integer>();
			}
		}

		public void addEdge(int v, int w) {
			E++;
			adj[v].add(w);
			adj[w].add(v);
		}

		public Iterable<Integer> adj(int v) {
			return adj[v];
		}

		public String toString() {
			StringBuilder s = new StringBuilder();
			String NEWLINE = System.getProperty("line.separator");
			s.append(V + " vertices, " + E + " edges " + NEWLINE);
			for (int v = 0; v < V; v++) {
				s.append(v + ": ");
				for (int w : adj[v]) {
					s.append(w + " ");
				}
				s.append(NEWLINE);
			}
			return s.toString();
		}
	}

	private int count;

	private boolean[] marked;
	private int[] id;
	private Graph G;

	public GraphTest(int V, int[][] edges) {
		this.marked = new boolean[V];
		this.id = new int[V];
		this.G = new Graph(V);
		for (int[] edge : edges) {
			this.G.addEdge(edge[0] - 1, edge[1] - 1);
		}
		for (int v = 0; v < V; v++) {
			if (!marked[v]) {
				dfs(v);
				count++;
			}
		}

	}

	private void dfs(int v) {
		marked[v] = true;
		id[v] = count;
		for (int w : this.G.adj(v)) {
			if (!marked[w]) {
				dfs(w);
			}
		}
	}

	public boolean connected(int v, int w) {
		return id[v] == id[w];
	}

	public Graph G() {
		return this.G;
	}

	public int count() {
		return count;
	}

	public static void main(String[] args) {
		int V = 5;
		int[][] edges = { { 1, 2 }, { 2, 3 }, { 4, 5 }, { 3, 4 } };
		GraphTest gt = new GraphTest(V, edges);
		System.out.println(gt.G());
		System.out.println(gt.count());
	}
}

9月19日,创新工厂笔试题:
给定一整型数组,若数组中某个下标值大的元素值小于某个下标值比它小的元素值,称这是一个反序。
即:数组a[]; 对于i < j 且 a[i] > a[j],则称这是一个反序。
给定一个数组,要求写一个函数,计算出这个数组里所有反序的个数
归并排序
package com.duoduo.test;

public class NiXu {
	private static int[] aux;
	private static int count;

	private NiXu() {
	}

	public static int count() {
		return count;
	}

	public static void sort(int[] a) {
		aux = new int[a.length];
		count = 0;
		sort(a, 0, a.length - 1);
	}

	private static void sort(int[] a, int lo, int hi) {
		if (lo < hi) {
			int mid = lo + (hi - lo) / 2;
			sort(a, lo, mid);
			sort(a, mid + 1, hi);
			if (a[mid] > a[mid + 1]) {
				merge(a, lo, mid, hi);
			}
		}
	}

	// lo ~ mid 应为 小序列,如果mid~hi
	//以下为引用网上一哥们的解释:
	// 举个例子,原序列是9 10 2 4 3
	// 最后要合并的两个左右序列是2 9 10 和 3 4
	// 刚开始a[i]=2 a[j] = 3,a[i]<a[j]不存在逆序对,将i++,a[i]->9
	// 这时候a[i]>a[j],存在逆序对,并且前一个序列中a[i+1...mid]因为是已经排序的,
	// 后面的每个数肯定也大于a[i],当然也大于a[j],当然也和a[j]成逆序对,这时候的逆序对的个数应该为mid-i+1
	private static void merge(int[] a, int lo, int mid, int hi) {
		for (int k = lo; k <= hi; k++) {
			aux[k] = a[k];
		}
		int i = lo;
		int j = mid + 1;
		int k = lo;
		while (i <= mid && j <= hi) {
			if (aux[i] <= aux[j]) {
				a[k++] = aux[i++];
			} else {
				count += (mid - i + 1);
				a[k++] = aux[j++];
			}
		}
		while (i <= mid) {
			a[k++] = aux[i++];
		}
		while (j <= hi) {
			a[k++] = aux[j++];
		}
	}

	public static void main(String[] args) {
		int[] a = { 9, 10, 2, 4, 3 };
		sort(a);
		System.out.println(count());
		for (int i : a) {
			System.out.print(i + " ");
		}
	}

}

9月20日,创新工厂南京站笔试:
已知字符串里的字符是互不相同的,现在任意组合,比如ab,则输出aa,ab,ba,bb,编程按照字典序输出所有的组合。

全排列
mport java.util.Arrays;

public class QP {
	private char[] a;
	private int N;
	private char[] b;

	public QP(String str) {
		a = str.toCharArray();
		b = new char[a.length];
		N = a.length;
		Arrays.sort(a);
		perm(0);
	}

	private void perm(int pos) {
		if (pos == N) {
			print(b);
		} else {
			for (int i = 0; i < N; i++) {
				b[pos] = a[i];
				perm(pos + 1);
			}
		}
	}

	private void print(char[] a) {
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i]);
		}
		System.out.println();
	}

	public static void main(String[] args) {
		QP qp = new QP("abc");
	}
}


栈即可解决

package com.duoduo.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.Map.Entry;

public class KuHao {
	private final static Map<Character, Character> map;
	private final static Map<Character, Character> reverse_map;
	static {
		map = new HashMap<Character, Character>();
		reverse_map = new HashMap<Character, Character>();
		map.put(')', '(');
		map.put(']', '[');
		map.put('}', '{');
		Iterator<Entry<Character, Character>> iter = map.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<Character, Character> entry = iter.next();
			reverse_map.put(entry.getValue(), entry.getKey());
		}
	}

	public static boolean isValidSeq(String input) {
		Stack<Character> stack = new Stack<Character>();
		int N = input.length();
		for (int i = 0; i < N; i++) {
			char ch = input.charAt(i);
			// ch 为左括号的话直接入栈
			if (!map.containsKey(ch)) {
				stack.push(ch);
			} else {
				if (stack.size() == 0) {
					return false;
				}
				if (map.get(ch) != stack.pop()) {
					return false;
				}
			}
		}
		if (stack.size() > 0) {
			return false;
		}
		return true;
	}

	public static String fixSeq(String input) {
		if (isValidSeq(input)) {
			return input;
		}
		Stack<Character> stack = new Stack<Character>();
		List<Character> result = new ArrayList<Character>();
		int N = input.length();
		for (int i = 0; i < N; i++) {
			char ch = input.charAt(i);
			// ch 为左括号的话直接入栈,加入结果集
			if (!map.containsKey(ch)) {
				stack.push(ch);
				result.add(ch);
			} else {
				// 如果栈为空,则将对应的左括号和右括号加入结果集
				if (stack.size() == 0) {
					result.add(map.get(ch));
					result.add(ch);
					continue;
				} else {
					// 如果栈不为空,并且不匹配,则找到左括号然后将ch加进去
					if (map.get(ch) != stack.peek()) {
						result.add(map.get(ch));
						result.add(ch);
					} else {
						// 匹配直接加入右括号
						stack.pop();
						result.add(ch);
					}
				}

			}
		}
		while (!stack.isEmpty()) {
			result.add(reverse_map.get(stack.pop()));
		}
		int M = result.size();
		char[] r = new char[M];
		for (int i = 0; i < M; i++) {
			r[i] = result.get(i);
		}
		return new String(r);

	}

	public static void main(String[] args) {
		String[] test = { "{}", "{{}", "{[]}", "{[{({})}]}", "{[]]}", "]]}"

		};
		for (String str : test) {
			System.out.println(isValidSeq(str));
			System.out.println(fixSeq(str));
			System.out.println(" == ");
		}

	}
}


死锁

死锁的四个必要条件

互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
循环等待条件(Circular wait):系统中若干进程组成环路,改环路中每个进程都在等待相邻进程正占用的资源。

http://blog.csdn.net/wlq1983/article/details/3022157

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值