算法题:最大获利,哲学家就餐,和为N整数,爬楼梯,大文件交集,分堆大量硬币
来源:互联网 发布:人工智能 电子书 编辑:程序博客网 时间:2024/06/10 08:44
本部分包括几个算法题:(1)股价序列求最大获利 (2)哲学家就餐问题 (3)求和N的所有非重复整数的集合 (4)一步或两步走楼梯,到N共有多少走法 (5)求两个超大放置url的文件的交集 (6)如何分出两堆正面相等的硬币
(1) 股价序列求最大获利:
题目:一个股价序列Input,里面有N个数值,每个数值表示不同时间段的股价,问求什么时间买卖获利最大及获得的最大利润。时间复杂度O(N),空间复杂度O(1),可以破坏原股价序列。
思路:股票肯定是卖的股价要比买的股价高,才能获得最大的利润,所以本题的思路是首先截取上升的曲线,然后比较每条上升的曲线的gap值,比较gap值即可。本题可以继续优化,后续再优化吧。
public class Counter1 {/** * @param args */public static void main(String[] args) { int[] input={10,9,2,3,4,3,2,4,5,6,5,4,2,1,8,9}; System.out.println("original length:"+input.length);int j=0;boolean begin=false;for(int i=1;i<input.length;i++){int temp=input[i]-input[i-1];if(temp>0){if(!begin){input[j]=input[i-1];input[j+1]=input[i];j++;begin=true;continue;}if(input[j]!=input[i-1]){input[j+1]=input[i-1];input[j+2]=input[i];j+=2;}else{input[j+1]=input[i];j+=1;}}}j++;input[j]=-1;for(int i=0;i<input.length;i++){if(input[i]!=-1){System.out.println("get upper line i="+i+",val="+input[i]);}else{break;}}System.out.println("extract the gap");j=0;begin=false;for(int i=1;i<input.length;i++){if(input[i]==-1){break;}else{if(input[i]>input[i-1]){if(!begin){input[j]=input[i-1];begin=true;j++;}input[j]=input[i];}else{j++;input[j]=input[i];j++;}}}j++;input[j]=-1;for(int i=0;i<input.length;i++){if(input[i]!=-1){System.out.println("extract the upper i="+i+",val="+input[i]);}else{break;}}System.out.println("compute the gap"); int gap=0;for(int i=1;i<input.length;i+=2){if(input[i]==-1){break;}else{int tgap=input[i]-input[i-1];if(tgap>gap){gap=tgap;}}}System.out.println("the biggest gap="+gap);}}
(2) 哲学家就餐问题, 五个哲学家围在圆桌边, : 每两人间有一只筷子, : 哲学家的行动顺序为 思考-》拿筷子-》吃饭 -》放筷子 -》思考(每一步时间随机),哲学家要吃饭,必须把左右两边的筷子都拿起, : 这样就有可能产生死锁,比如每个哲学家都可能拿起左边的筷子,等待右边的筷子。 设一个数组state[],保存每个哲学家的状态:thinking,hungry,eating
import java.text.SimpleDateFormat;import java.util.Date;import java.util.Random;public class Philosopher extends Thread {public static final int THINKING = 0;public static final int START = 1;public static final int EATING = 2;public static final int FINISHED = 3;// 每步等待0 - 50毫秒public static final int MAX_WAIT = 50;public static Random ran = new Random();private Table table;private int chair;private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss:SS");public Philosopher(Table table, int chair) {this.table = table;this.chair = chair;}public void run() {try {do {switch (table.getStatus(this.chair)) {case Philosopher.THINKING: {Thread.sleep(ran.nextInt(Philosopher.MAX_WAIT));if (table.test(this.chair)) {table.setStatus(this.chair, Philosopher.START);log(chair + " 拿起了筷子");}break;}case Philosopher.START: {Thread.sleep(ran.nextInt(Philosopher.MAX_WAIT));table.setStatus(this.chair, Philosopher.EATING);log(chair + " 开始吃饭 ");break;}case Philosopher.EATING: {Thread.sleep(ran.nextInt(Philosopher.MAX_WAIT));table.setStatus(this.chair, Philosopher.FINISHED);log(chair + " 吃饭完毕, 放下了筷子");break;}case Philosopher.FINISHED: {Thread.sleep(ran.nextInt(Philosopher.MAX_WAIT));table.setStatus(this.chair, Philosopher.THINKING);log(chair + " 开始下一次思考");break;}}} while (table.isRunning());} catch (Exception e) {e.printStackTrace();}}public void log(String msg) {System.out.println(sdf.format(new Date()) +",哲学家"+ msg);}public static void main(String[] args) {// 10个哲学家, 这下搞大了...Table table = new Table(2);table.start();}}class Table {private Philosopher[] all;private int[] status_list;private boolean running = true;private long start_time;// 3秒后结束运行public static final int TIME_OUT = 2000;public Table(int count) {all = new Philosopher[count];status_list = new int[count];for (int i = 0; i < count; i++) {all[i] = new Philosopher(this, i);status_list[i] = Philosopher.THINKING;}}public void start() {start_time = System.currentTimeMillis();for (int i = 0, len = all.length; i < len; i++) {new Thread(all[i]).start();}}public int getStatus(int chair) {return status_list[chair];}public void setStatus(int chair, int status) {status_list[chair] = status;}public boolean test(int chair) {synchronized (this) {if (System.currentTimeMillis() - start_time > Table.TIME_OUT) {this.running = false;}boolean result = false;int previous = this.getStatus((chair == 0) ? all.length - 1: chair - 1); 每个chair的左边筷子,注意第0个chairint next = this.getStatus((chair == all.length - 1) ? 0 : chair + 1); 每个chair的右边筷子,注意最后一个chairif ((previous == Philosopher.THINKING || previous == Philosopher.FINISHED)&& (next == Philosopher.THINKING || next == Philosopher.FINISHED)) {result = true;}return result;}}public boolean isRunning() {return this.running;}}
还有使用图形化界面的方式更加形象的解决此问题
http://www.cnblogs.com/rollenholt/archive/2011/09/15/2178004.html
(3)求和为N的所有数的集合, 描述:对于和20进行分解,分解成一大一小,大的从19开始依次递减,对于小的进行再次分解,递归求解,如:可分解成13 7 其中7又可分解成 6 1,5 2,4 3 3 可分解成2 1,然后依次类推
public class AnySumN { int n; AnySumN(int n){ this.n = n; } public void f(String string,int num,int max){ for(int i=max;i>0;i--){ String tempString; if(num+i==n){ tempString = string + " " + String.valueOf(i); System.out.println(tempString); }else if(num+i<n && i-1>0){ tempString = string + " " + String.valueOf(i); f(tempString,num+i,i-1); } } } public void direct(){ if(n-1>0) for(int i=n-1;i>0;i--) if(i-1>0) f(String.valueOf(i),i,i-1); } public static void main(String[] args) { AnySumN asn = new AnySumN(6); asn.direct(); }}来源于:http://my.csdn.net/oceanethan/code/detail/40605
http://blog.csdn.net/ryj111/article/details/5192969
(3) 一个楼梯有20级,每次走1级或两级,请问从底走到顶一共有多少种走法?
分析:假设从底走到第n级的走法有f(n)种,关键的关键:走到第n级有两个方法,一个是从(n-1)级走一步,另一个是从第(n-2)级走两步,前者有f(n-1)种方法,后者有f(n-2)种方法,所以有f(n)=f(n-1)+f(n-2),还有f(0)=1,f(1)=1.
递归编程实现
方法1
#include <stdio.h>int f(int n){ if(n==0 || n==1) return 1; else return f(n-1)+f(n-2);}int main(){ printf("%d/n",f(20)); return 0;}
现在来说说动态规划的基本思想动态规划的关键是发现子问题和怎么记录子问题,以上面的例子说明
(1) 对子问题可递归的求解,当n>1时,f(n)=f(n-1)+f(n-2);否则,f(1)=f(0)=1;
(2) 这些子问题是有重叠的,即求解某个问题时,某些子问题可能需要求解多次。例如求解f(5)时,f(2)就被求解了3次。
在上面两个条件下,用动态规划的方式来求解会高效很多。就是把子问题记录下来,每个子问题只求解一次,从而提高了效率。方法二
#include <stdio.h> int result[100]; int f(int n) { int res; if(result[n]>=0) return result[n]; if(n==0 || n==1) res=1; else res=f(n-1)+f(n-2); result[n]=res; return res; } int main() { int i; for(i=0;i<=20;i++) result[i]=-1; printf("%d/n",f(20)); return 0; }方法三
#include <stdio.h>int f[100];int main(){ int i; f[0]=1; f[1]=1; for(i=2;i<=20;i++) f[i]=f[i-1]+f[i-2]; printf("%d",f[20]); return 0;}
方法三是否让你想起了那个兔子繁殖的问题呢?
小结一下
动态规划,采用分治的策略,把求最优解问题分解为求若干子问题的最优解,记录子问题的解,化繁为简,很实用,也很高效。
/** * Returns a hash code for this string. The hash code for a * <code>String</code> object is computed as * <blockquote><pre> * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1] * </pre></blockquote> * using <code>int</code> arithmetic, where <code>s[i]</code> is the * <i>i</i>th character of the string, <code>n</code> is the length of * the string, and <code>^</code> indicates exponentiation. * (The hash value of the empty string is zero.) * * @return a hash code value for this object. */ public int hashCode() { int h = hash; if (h == 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; //31 上文构造方法参数mulBase } hash = h; } return h; }
import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestRegex { public static boolean isboolIP(String ipAddress){ String one="(2[5][0-5]|2[0-4]\\d|1\\d{2}|\\d{1,2})"; String ip=one+"\\."+one+"\\."+one+"\\."+one; Pattern pattern = Pattern.compile(ip); Matcher matcher = pattern.matcher(ipAddress); return matcher.matches(); }}
(6)一大堆硬币,有正有反,现在蒙着眼睛如何让你分,并且硬币的正反面摸不出来,只可以进行翻转,如何分堆才能将分成的两堆硬币中正面个数相同。
- 算法题:最大获利,哲学家就餐,和为N整数,爬楼梯,大文件交集,分堆大量硬币
- 算法讨论:哲学家就餐问题
- 哲学家就餐
- 哲学家就餐
- [转]算法讨论:哲学家就餐问题
- 币值为25分、10分、5分和1分的硬币,计算n分有几种表示方法
- 找出n个整数中的最大和第二大的
- 给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有多少种表示法。
- 给定数量不限的硬币,币值为25分,10分,5分和1分,编写代码计算n分有几种表示法
- 换零钱:有数量不限的硬币,币值为25分、10分、5分和1分,请编写代码计算n分有几种表示法。
- 有数量不限的硬币,币值为25分、10分、5分和1分,请编写代码计算n分有几种表示法
- 面试算法题:爬楼梯,N级楼梯有多少种走法?
- 文件互斥的方式实现哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 哲学家就餐问题
- 5哲学家就餐
- 哲学家就餐问题 锁
- FRM-92101: There was a failure in the Forms Server during startup.
- 准备把evernote里面的东西转出来了
- POJ-1861-Network
- RQNOJ-252-公司聚会(线性dp)
- 5、struts2访问Servlet API及web应用单元测试、结果类型及项目开发模式
- 算法题:最大获利,哲学家就餐,和为N整数,爬楼梯,大文件交集,分堆大量硬币
- 浏览器CSS Hack
- hashcode()和equals()方法
- Navicate for MySQL建立外键
- 副本结构Swift 1.8.0(Grizzly) 中region的理解
- 立体匹配十大概念综述 .
- C++中的算法algorithm
- node.js 加载adds on module no found
- CMD type命令