算法-java(2)

来源:互联网 发布:浙江淘宝网络有限公司 编辑:程序博客网 时间:2024/06/10 07:24

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

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 pHead2) {        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();    }}
0 0
原创粉丝点击