摘要: 如果用一颗二叉树表示加减乘除及0-9的数字构成的数学表达式,对二叉树进行后序遍历得到的就是后缀表达式。后缀表达式可以通过堆栈直接计算其值。如果输入的是中缀表达式,下面的方法toBinaryTree()将它转化为二叉树。代码:import java.util.ArrayList;import java.util.List;import java.util.Stack;/** * * @author ljs * 2011-05-24 * * 把中缀表达式转换成一棵二叉树,然后通过后序遍历计算表达式的值 * 1. unary operator like -3 is not supported * 2 阅读全文
posted @ 2011-06-05 22:25 ljsspace 阅读(1573) 评论(0) 推荐(0) 编辑
摘要: 在我的另外一篇文章"正整数中数字1的计数问题(上)"中,实现了一个简单的算法来计算f(n)。该算法由于只考虑相邻两个数的变化规律,因此在计算单个长整数时(比如n=911111111099999009L),可能要很长时间才能算完,显然该算法适用范围比较狭小。本文继续围绕那道Google面试题,探讨一个计算单个值f(n)的快速算法以及如何求出所有满足f(i)=i这样的整数(对很大的数计算时间能达到毫秒数量级)。分析:首先注意到,比如要计算i=3260这样的f(i),在算到i=3200的时候,其实又重复了以前的计算,即重新计算1到60的值。本算法就是基于这个考虑,将一个数拆成左右 阅读全文
posted @ 2011-06-05 22:24 ljsspace 阅读(386) 评论(0) 推荐(0) 编辑
摘要: 正整数中数字1的计数问题(上)原题出自Google的一道比较老的面试题:Consider a function which, for a given whole number n, returns the number of ones required when writing out allnumbers between 0 and n. For example, f(13)=6. Notice that f(1)=1. What is the next largest n such that f(n)=n?本实现没有利用可能存在的数学公式,只考虑相邻两个数得变化规律,因此运行效率并不理想。 阅读全文
posted @ 2011-06-05 22:23 ljsspace 阅读(228) 评论(0) 推荐(0) 编辑
摘要: (原题出自微软公司面试题)问题如下:有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。例如: var a=[100,99,98,1,2, 3];var b=[1, 2, 3, 4,5,40];分析:通过交换的方式,最终的状态是在保证两个序列中元素个数相同的条件下,任何一个元素都可以位于两个序列中的任何一个。这样问题可以转化为:在一个长度为2*n的整数序列中,如何将元素个数分成两个子集,记每个子集的元素之和分别为S1和S2,使得|S1-S2|最小。显然这是一个最优化问题,如果用brute-force方法, 阅读全文
posted @ 2011-06-05 22:22 ljsspace 阅读(493) 评论(0) 推荐(0) 编辑
摘要: 二进制方法中,只需要移位(<<和>>)和加减操作(+和-),不像欧几里德算法中需要乘法和除法运算。虽然算法效率更高,但是程序的可读性和可维护性差一些。如果设d=gcd(u,v) = u.x + v.y, 本算法涉及到六种操作:1)已知ext_gcd(u,v)如何求ext_gcd(u,2v)=u'.x' + v'.y',其中u为奇数,v可奇可偶,d=gcd(u,v)为奇数;2)已知ext_gcd(u,v)如何求ext_gcd(2u,v)=u'.x' + v'.y',其中v为奇数,u可奇可偶,d=gcd(u,v 阅读全文
posted @ 2011-06-05 22:21 ljsspace 阅读(430) 评论(0) 推荐(0) 编辑
摘要: 扩展的gcd算法即除了计算gcd(m,n)还要计算整数x和y,使之满足gcd(m,n) = m.x + n.y。 下面的算法中使用迭代方式。 extendedGCD2方法是extendedGCD的简化版本,考虑到在初值向量r{-1} = [1 0], r{0} = [0 1]下,满足递推关系:r{i} = r{i-2} - q{i}.r{i-1}。采用Euclid's算法时,不仅要r(余数)的值,还需要q(商)的值。本例实现参考了Wikipedia中介绍的迭代方法:http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm/** 阅读全文
posted @ 2011-06-05 22:20 ljsspace 阅读(527) 评论(0) 推荐(0) 编辑
摘要: 二进制GCD算法基本原理是:先用移位的方式对两个数除2,直到两个数不同时为偶数。然后将剩下的偶数(如果有的话)做同样的操作,这样做的原因是如果u和v中u为偶数,v为奇数,则有gcd(u,v)=gcd(u/2,v)。到这时,两个数都是奇数,将两个数相减(因为gcd(u,v) = gcd(u-v,v)),得到的是偶数t,对t也移位直到t为奇数。每次将最大的数用t替换。二进制GCD算法优点是只需用减法和二进制移位运算,不像Euclid's算法需要用除法,这在某些嵌入式系统中可能排上用场。本例实现参考了<<计算机编程的艺术>>(Knuth)第二卷中介绍的算法。/** * 阅读全文
posted @ 2011-06-05 22:19 ljsspace 阅读(540) 评论(0) 推荐(0) 编辑
摘要: 求两个整数的GCD有两个方法:采用欧几里得算法(Euclid's Algorithm)和二进制GCD算法, 这里实现的是欧几里得算法。欧几里得算法基本原理很简单,即: m = q1.n + r1m2= q2.n2 + r2 ....mi = qi.ni + ri其中m2=n, n2=r1....gcd(m,n) = gcd(m2,n2) = gcd(mi,ni)....直到ri=0(因为0<=ri<ni,所以ri可以收敛到0)。实现:/** * * @author ljs 2011-5-17 * * solve gcd(m,n) using Euclid's Alg 阅读全文
posted @ 2011-06-05 22:18 ljsspace 阅读(1033) 评论(0) 推荐(0) 编辑
摘要: 用Eratosthenes筛子法:import java.util.ArrayList;import java.util.List;/** * * @author ljs * Sieve of Eratosthenes: determine the prime numbers within the range 1....n (n>0) * */public class Sieve { //intput: n is an positive integer (n>0) //output: a list of primes from 1 to n, as 2,3,5.... public 阅读全文
posted @ 2011-06-05 22:15 ljsspace 阅读(428) 评论(0) 推荐(0) 编辑
摘要: 原问题位于:http://poj.org/problem?id=1015以下为问题描述的摘录:In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of members of the general public. Every time a trial is set to begin, a jury has to be selected, which is done as follows. First, several people are drawn r 阅读全文
posted @ 2011-06-05 22:09 ljsspace 阅读(287) 评论(0) 推荐(0) 编辑