算法-java(2)
2016-03-29 10:34
609 查看
1,字符串移位
给定两个字符串s1和s2,判断s2能否被s1循环移位得到的字符串包含。如:
s1=AABCD,s2=CDAA,,返回true,
s1=ABCD,s2=ACBD。返回false
分析:若s2能被s1循环移位得到,则s2一定在s1s1上
,即CDAA一定在AABCDAABCD上。
s1s1.indexOf(s2)!=-1,即可。
或者s1s1.contains(s2)来判断
2,计算字符串的相似度,
相似度等于 “距离+1”的倒数。distance
3,反转链表
4,输入两个链表,找出它们的第一个公共结点
分析:
分别求出两个链表的长度len1和len2,计算出长度差flag=len1-len2,
5,重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
6,分层遍历二叉树
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
7,判断单链表是否有环–快慢指针
8,求二叉树节点的最大距离
9,圆圈中最后剩下的数
他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友,
一条长廊里依次装有n(1≤n≤65535)盏电灯,从头到尾编号1、2、3、…n-1、n。每盏电灯由一个拉线开关控制。开始,电灯全部关着。
有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下;接着第二个学生把号码凡是2的倍数的电灯的开关拉一下;接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。
注:电灯数和学生数一致。不能写笨拙的双重循环(优化过的是可以的),会运行超时。本题有运行时间限制(一说10000ms)。
分析:
对于任何一盏灯,由于它原来不亮,那么当它的开关被按奇数次时,灯是开着的;当它的开关被按偶数次时,灯是关着的;一盏灯的开关被按的次数,恰等于这盏灯的编号的因数的个数;要求哪些灯还亮着,就是问哪些灯的编号的因数有奇数个.显然完全平方数有奇数个因数。每个数除以一个数A等于另一个数B,那么A和B都是它的因数,于是因数是成对出现的,但是要因数是奇数,就必须A=B所以这个数就必须是一个是的平方得到的。
给定两个字符串s1和s2,判断s2能否被s1循环移位得到的字符串包含。如:
s1=AABCD,s2=CDAA,,返回true,
s1=ABCD,s2=ACBD。返回false
分析:若s2能被s1循环移位得到,则s2一定在s1s1上
,即CDAA一定在AABCDAABCD上。
s1s1.indexOf(s2)!=-1,即可。
或者s1s1.contains(s2)来判断
2,计算字符串的相似度,
相似度等于 “距离+1”的倒数。distance
import java.util.*; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String a = scanner.nextLine(); String b = scanner.nextLine(); System.out.println(“1/”+stringDistance(a.toCharArray(), b.toCharArray())+1); }scanner.close(); } public int stringDistance(int[] a,int[] b){ int lena=a.length+1; int lenb=b.length+1; int[][] d=new int[lena][lenb]; for(int i=0;i<d.length;i++){ d[i][0]=i; } for(int i=0;i<d[0].length;i++){ d[0][i]=i; } int max=0; for(int i=1;i<d.length;i++){ for(int j=1;j<d[0].length;j++){ if(a[i-1]==b[j-1]){ d[i][j]=d[i-1][j-1]; }else{ d[i][j]=Math.min(d[i-1][j-1],Math.min(d[i][j-1],d[i-1][j]))+1; } } } return d[d.length-1][d[0].length-1]; } }
3,反转链表
public ListNode reverseList(ListNode head){ if(head==null||head.next==null) return head; ListNode pre=null; ListNode tmp=null; ListNode cur=head; while(cur!=null){ tmp=cur.next; cur.next=pre; pre=cur; cur=tmp; } return pre; }
4,输入两个链表,找出它们的第一个公共结点
分析:
分别求出两个链表的长度len1和len2,计算出长度差flag=len1-len2,
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ import java.util.*; public class Solution { public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead ec61 2) { if(pHead1==null||pHead2==null) return null; //计算pHead1的长度 int count1=0; ListNode p1=pHead1; while(p1!=null){ p1=p1.next; count1++; } //计算pHead2的长度 int count2=0; ListNode p2=pHead2; while(p2!=null){ p2=p2.next; count2++; } //计算出长度差 int flag=count1-count2; if(flag>0){ while(flag>0){ pHead1=pHead1.next; flag--; } while(pHead1!=pHead2){ pHead1=pHead1.next; pHead2=pHead2.next; } return pHead1; } if(flag<=0){ while(flag<0){ pHead2=pHead1=2.next; flag++; } while(pHead1!=pHead2){ pHead1=pHead1.next; pHead2=pHead2.next; } return pHead1; } return null; } }
5,重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode reConstructBinaryTree(int [] pre,int [] in) { TreeNode root=reConstructBinaryTree(int [] pre,0,pre.length-1,int [] in,0,in.length-1); return root; } //先序遍历的第一个节点为根节点。 //中序遍历根节点在中间,左边为左子树,右边为右子树 private TreeNode reConstructBinaryTree(int [] pre,int startp,int endp,int [] in,int startin,int endin){ if(startp>endp||startin>endin) return null; TreeNode root=pre[start]; for(int i=0;i<in.length;i++){ if(pre[start]==in[i]){ root.left=reConstructBinaryTree(pre,startp+1,startp+1+i-1-startin,in,startin,i-1); root.right=reConstructBinaryTree(pre,startp+i-startin+1,endp,in,i+1,endin); } } return root; } }
6,分层遍历二叉树
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
import java.util.ArrayList; import java.util.*; /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ //用一个ArrayList来保存数据 public ArrayList<Integer> PrintFromTopToBottom(TreeNode root){ ArrayList<Integer> list=ArrayList<Integer>(); LinkedList<TreeNode> queue=new LinkedList<TreeNode>(); if(root==null) return list; queue.offer(root); while(!queue.isEmpty()){ TreeNode node=queue.poll(); if(node.left!=null) queue.offer(node.left); if(node.right!=null) queue.offer(node.right); list.add(node.val); } return list; }
7,判断单链表是否有环–快慢指针
while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) return true; } return false;
8,求二叉树节点的最大距离
// 数据结构定义 struct NODE { NODE* pLeft; // 左子树 NODE* pRight; // 右子树 int nMaxLeft; // 左子树中的最长距离 int nMaxRight; // 右子树中的最长距离 char chValue; // 该节点的值 }; int nMaxLen = 0; // 寻找树中最长的两段距离 void FindMaxLen(NODE* pRoot) { // 遍历到叶子节点,返回 if(pRoot == NULL) { return; } // 如果左子树为空,那么该节点的左边最长距离为0 if(pRoot -> pLeft == NULL) { pRoot -> nMaxLeft = 0; } // 如果右子树为空,那么该节点的右边最长距离为0 if(pRoot -> pRight == NULL) { pRoot -> nMaxRight = 0; } // 如果左子树不为空,递归寻找左子树最长距离 if(pRoot -> pLeft != NULL) { FindMaxLen(pRoot -> pLeft); } // 如果右子树不为空,递归寻找右子树最长距离 if(pRoot -> pRight != NULL) { FindMaxLen(pRoot -> pRight); } // 计算左子树最长节点距离 if(pRoot -> pLeft != NULL) { int nTempMax = 0; if(pRoot -> pLeft -> nMaxLeft > pRoot -> pLeft -> nMaxRight) { nTempMax = pRoot -> pLeft -> nMaxLeft; } else { nTempMax = pRoot -> pLeft -> nMaxRight; } pRoot -> nMaxLeft = nTempMax + 1; } // 计算右子树最长节点距离 if(pRoot -> pRight != NULL) { int nTempMax = 0; if(pRoot -> pRight -> nMaxLeft > pRoot -> pRight -> nMaxRight) { nTempMax = pRoot -> pRight -> nMaxLeft; } else { nTempMax = pRoot -> pRight -> nMaxRight; } pRoot -> nMaxRight = nTempMax + 1; } // 更新最长距离 if(pRoot -> nMaxLeft + pRoot -> nMaxRight > nMaxLen) { nMaxLen = pRoot -> nMaxLeft + pRoot -> nMaxRight; } }
9,圆圈中最后剩下的数
他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友,
public int LastRemaining_Solution(int n, int m) { if(n==0) return -1; int s=0; for(int i=2;i<=n;i++){ s=(s+m)%i; } return s; }
一条长廊里依次装有n(1≤n≤65535)盏电灯,从头到尾编号1、2、3、…n-1、n。每盏电灯由一个拉线开关控制。开始,电灯全部关着。
有n个学生从长廊穿过。第一个学生把号码凡是1的倍数的电灯的开关拉一下;接着第二个学生把号码凡是2的倍数的电灯的开关拉一下;接着第三个学生把号码凡是3的倍数的电灯的开关拉一下;如此继续下去,最后第n个学生把号码凡是n的倍数的电灯的开关拉一下。n个学生按此规定走完后,长廊里电灯有几盏亮着。
注:电灯数和学生数一致。不能写笨拙的双重循环(优化过的是可以的),会运行超时。本题有运行时间限制(一说10000ms)。
分析:
对于任何一盏灯,由于它原来不亮,那么当它的开关被按奇数次时,灯是开着的;当它的开关被按偶数次时,灯是关着的;一盏灯的开关被按的次数,恰等于这盏灯的编号的因数的个数;要求哪些灯还亮着,就是问哪些灯的编号的因数有奇数个.显然完全平方数有奇数个因数。每个数除以一个数A等于另一个数B,那么A和B都是它的因数,于是因数是成对出现的,但是要因数是奇数,就必须A=B所以这个数就必须是一个是的平方得到的。
import java.util.*; public class LiangDengShu { public static void main(String[] args) { // TODO Auto-generated method stub Scanner sc=new Scanner(System.in); int n=sc.nextInt(); int count=0; for(int i=1;;i++){ if(i*i>n){ break; }else{ count++; } } System.out.println(count); sc.close(); } }
相关文章推荐
- spring多数据源配置
- JAVA 学习之标识符
- java中接口抽象类的标准案例
- java中foreach的使用格式
- Hibernate 集合属性的操作
- Eclipse配置(Mac版)
- java中Comparable接口(比较器)的使用
- java15天
- java使用poi操作Excel
- 安装JDK提示: 该项不适于在指定状态下使用的错误
- java 求数字在排序数组中出现的次数(O(logn))
- javaweb入门
- java基础知识汇总6(html篇)
- eclipse中使用git进行版本控制
- Java随机数
- java 读取文件
- java基础知识总结5
- Java学习笔记(十六):UML类图符号以及各种关系
- Java中hashCode的作用
- java基础知识汇总4