剑指offer(31-40)

原创 2016年08月28日 16:14:45
31.求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
    思路:
代码:
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
    
        int count=0;
        
        for(int i=1;i<=n;i++){   
            int tmp=i;
            while(tmp!=0){
                if(tmp%10==1)
                	count++;
                
                tmp=tmp/10;
            }
        }
        
        return count;
    }
}

32.输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
    思路:
先将整型数组转换成String数组,然后将String数组排序,最后将排好序的字符串数组拼接出来。关键就是制定排序规则。
 * 排序规则如下:
 * 若ab > ba 则 a > b,
 * 若ab < ba 则 a < b,
 * 若ab = ba 则 a = b;
 * 解释说明:
 * 比如 "3"< "31"但是 "331"> "313",所以要将二者拼接起来进行比较
代码:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {

        if(numbers == null || numbers.length == 0) 
            return "";
                  
        int len=numbers.length;        
        String[] s=new String[len];
        StringBuilder sb=new StringBuilder();
        
        for(int i=0;i<len;i++){
            s[i]=String.valueOf(numbers[i]);
        }
        
        //重新定义比较规则
         Arrays.sort(s,new Comparator<String>(){
            @Override
            public int compare(String s1, String s2) {
          	String c1=s1+s2;
                String c2=s2+s1;
                return c1.compareTo(c2);
            }
        });
        
        for(int i=0;i<len;i++){
            sb.append(s[i]);
        }
        
        return sb.toString();
    }
}

33.把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
    思路:要注意,后面的丑数是有前一个丑数乘以2,3,5中的一个得来。因此可以用动态规划去解
代码:
public class Solution {
    public int GetUglyNumber_Solution(int index) {
  
        if(index==0) 	return 0;    
        if(index==1)	return 1;
        
        int[] k=new int[index];
        k[0]=1;
        int t2=0;int t3=0;int t5=0;
        
        for(int i=1;i<index;i++){
            k[i]=Math.min(k[t2]*2,Math.min(k[t3]*3,k[t5]*5));
            if(k[i]==k[t2]*2) t2++;
            if(k[i]==k[t3]*3) t3++;
            if(k[i]==k[t5]*5) t5++;
        }
        
        return k[index-1];
    }
}

34.在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符,并返回它的位置
    思路:使用HashMap,第一遍存储,第二遍查询
代码:
import java.util.HashMap;

public class Solution {
    public int FirstNotRepeatingChar(String str) {
       
        if(str==null||str.length()==0)
            return -1;
        
        HashMap<Character,Integer> map=new HashMap<Character,Integer>();
        char[] c=str.toCharArray();
        int r=-1;
        
        for(int i=0;i<c.length;i++){
            if(map.get(c[i])==null){
                
                map.put(c[i],1);
            }else{
                
                map.put(c[i],map.get(c[i])+1);
            }
        }
        
        
        for(int i=0;i<c.length;i++){
            if(map.get(c[i])==1){
                r=i;
                break;
            }
            
        }
        
        return r;
    }
}

35.在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007 
输入描述:

题目保证输入的数组中没有的相同的数字

数据范围:

对于%50的数据,size<=10^4

对于%75的数据,size<=10^5

对于%100的数据,size<=2*10^5



输入例子:
1,2,3,4,5,6,7,0

输出例子:
7
    思路:

36.输入两个链表,找出它们的第一个公共结点。
    思路:用两个指针扫描”两个链表“,最终两个指针到达 null 或者到达公共结点。
代码:
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
 
        ListNode p1=pHead1;
        ListNode p2=pHead2;
        
        while(p1!=p2){
            
            p1=p1==null?p1=pHead2:p1.next;
            p2=p2==null?p2=pHead1:p2.next;
            
        }
        
        return p1;
    }
}

37.统计一个数字在排序数组中出现的次数。
    思路:定义一个计数变量,循环一次,
代码:
public class Solution {
    public int GetNumberOfK(int [] array , int k) {
       
        if(array==null||array.length==0)
            return 0;
        
        int count=0;
        for(int i=0;i<array.length;i++){
            
            if(k==array[i]){
                count++;
            } 
        }
        
        return count;
        
    }
}

38.输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
    思路:假如是空节点,则返回0;
               否则,原树的深度由左右子树中深度较的深度加1,为原树的深度。
代码:
/*
public class TreeNode {
	int val = 0;
	TreeNode left = null;
	TreeNode right = null;
	public TreeNode(int val) {
        this.val = val;
    }
};*/
public class Solution {
	public int TreeDepth(TreeNode pRoot){
        
        if(pRoot==null)
            return 0;
        
        return Math.max(1+TreeDepth(pRoot.left),1+TreeDepth(pRoot.right));
    
    }
}

39.输入一棵二叉树,判断该二叉树是否是平衡二叉树。
    思路:  后续遍历时,遍历到一个节点,其左右子树已经遍历  依次自底向上判断,每个节点只需要遍历一次
代码:
public class Solution {
    
    private boolean isBalanced=true;
    
    public boolean IsBalanced_Solution(TreeNode root) {
                    
        getDepth(root);    
        
        return isBalanced;
    }
    
    public int getDepth(TreeNode root){
        
        if(root==null)
            return 0;
        
        int left=getDepth(root.left);
        int right=getDepth(root.right);
        
        if(Math.abs(left-right)>1)
           isBalanced=false;
        
        return right>left?right+1:left+1;
        
    }
    
}

40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
    思路:使用ArrayList,如果没包含就添加,包含就移除
代码:
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
import java.util.ArrayList;

public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        
        ArrayList<Integer> list=new ArrayList<Integer>();
        
        for(int i=0;i<array.length;i++){
            
            if(!list.contains(array[i])){
                list.add(array[i]);
            }else{
                list.remove(new Integer(array[i]));
            }
            
            if(list.size()>1){
                
                num1[0]=list.get(0);
                num2[0]=list.get(1);
                
            }
            
        }
        
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

剑指offer--发散思维(23、31、33、40、41、42、47、49、55)

offer23 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少总跳法,并分析算法的时间复杂度。 遇到不会的题目可以想想递归,假设 f(n),表示n级台阶的跳法,那么最后一跳只有两种...

【剑指Offer】鸟瞰50题之31 - 40题

面试题31连续子数组的最大和  面试题32从1到n整数中1出现的次数  面试题33把数组排成最小的数  面试题34丑数  面试题35第一个只出现一次的字符  面试题36数组中的逆序对 面试题37两个链...

剑指offer 试题31~40

试题31:栈的压入、弹出序列分析一下,有以下情况: 压入序列的当前元素和弹出序列的当前元素相等,那么只需要把压入序列的当前元素入栈并出栈,就和弹出序列对应上了,故两个序列都往前走一步 压入序列的当前元...
  • jsszwc
  • jsszwc
  • 2017年12月08日 17:15
  • 12

剑指offer学习笔记(Java实现)(31-40)

题目31:连续子数组的最大和在数组中找一个连续子数组,使它的和最大。我的方法:利用一个local维护局部子数组最大和,一个global维护全局子数组最大和。因为子数组要连续,local[i]只能出现两...

【剑指offer】31-40题

31.求连续子数组(包含负数)的最大和思路:若和小于0,则将最大和置为当前值,否则计算最大和。代码实现:public int FindGreatestSumOfSubArray(int[] array...

剑指Offer系列-面试题40:数组中只出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。 思路:利用异或的特点,一个数的二进制异或自己,结果...

剑指offer 面试题40 数组中只出现一次的数字

剑指offer 面试题40 数组中只出现一次的数字 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出两个只出现了一次的数字。要求时间复杂度是 O(n),空间复杂度是 O...

剑指Offer面试题40(Java版):数组出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。  * 请些程序找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1) 例如输入数组{2,4,3,6,3,2,5,...

异或的应用 及剑指offer 面试 40 数组中只出现一次的数字

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27568975     这篇文章没有代码,介绍的是纯理论的思路。  ...

剑指offer系列-T40找出数组中只出现一次的2个数

本人对java语言更熟悉,所以剑指offer代码都是通过Java实现,且涉及的核心代码全部通过牛客网的测试用例检查,感谢牛客网为我检验程序提供了极大帮助!main函数是为了在自己运行程序时,运行结果更...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:剑指offer(31-40)
举报原因:
原因补充:

(最多只允许输入30个字)