剑指offer 31~40

剑指offer 31~40

求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
      int count = 0;
        for (int i = 1; i <= n; i++) {
            int j = i;
            while (i != 0) {
                if (i % 10 == 1)
                    count++;
                i /= 10;
            }
            i = j;
        }
        return count;
    }
}
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
import java.util.ArrayList;

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

        if (numbers == null) return null;
        StringBuilder stringBuilder = new StringBuilder();
        String pre, last;
        for (int i = 0; i < numbers.length; i++) {
            for (int j = i + 1; j < numbers.length; j++) {

                pre = numbers[i] + "" + numbers[j];
                last = numbers[j] + "" + numbers[i];
                if (compare(pre, last) > 0) {
                    exchange(numbers, i, j);
                }
            }
            stringBuilder.append(numbers[i]);
        }

        return stringBuilder.toString();
    }

    static void exchange(int[] nubers, int i, int j) {
        int temp = nubers[i];
        nubers[i] = nubers[j];
        nubers[j] = temp;
    }

    static int compare(String pre, String last) {
        int len1 = pre.length();
        int len2 = last.length();

        int min = Math.min(len1, len2);
        char cpre[] = pre.toCharArray();
        char clast[] = last.toCharArray();
        int k = 0;
        while (k < min) {
            char c1 = cpre[k];
            char c2 = clast[k];
            if (c1 != c2)
                return c1 - c2;
            k++;
        }
        return len1 - len2;
    }
}
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
public class Solution {
    public int GetUglyNumber_Solution(int index) {
         if (index == 0) return 0;
        
        int a[] = new int[index];
        int t2 = 0, t3 = 0, t5 = 0;
        a[0] = 1;
        for (int i = 1; i < index; i++) {
            a[i] = Cmin(a[t2] * 2, a[t3] * 3, a[t5] * 5);

            if (a[t2] * 2 == a[i]) t2++;
            if (a[t3] * 3 == a[i]) t3++;
            if (a[t5] * 5 == a[i]) t5++;
        }
        return a[index - 1];
    }

    static int Cmin(int a, int b, int c) {
        int min = Math.min(a, b);
        return Math.min(min, c);
    }
}
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Solution {
    public int FirstNotRepeatingChar(String str) {
      
        char chStr[] = str.toCharArray();
        Arrays.sort(chStr);
        int ch[] = new int[26], value = 1;
        HashMap hashMap = new HashMap<Character, Integer>();
        for (int i = 0; i < chStr.length - 1; i++) {
            if (chStr[i] == chStr[i + 1]) {
                value++;
                hashMap.put(chStr[i], value);
            } else {
                value = 1;
            }
        }

        Iterator iterator = hashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Character, Integer> entry = (Map.Entry) iterator.next();
            Character key = entry.getKey();
            if (entry.getValue() >= 1) {
                str = str.replace(Character.toString(key), "*");
            }
        }
        int i;
        for( i=0;i<str.length();i++){
            if(str.charAt(i)!='*')return i;
        }
        return -1;
    }
}
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007

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

数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5

示例1

输入
1,2,3,4,5,6,7,0

输出
7

public class Solution {
    public int InversePairs(int [] array) {
         int len = array.length;
        if (array == null || array.length == 0) return 0;
        return mergeSort(array, 0, len - 1);
    }

    static int mergeSort(int[] array, int start, int end) {
        if (end == start) return 0;
        int mid = (start + end) / 2;
        int leftCount = mergeSort(array, start, mid);
        int rightCount = mergeSort(array, mid + 1, end);

        int i = mid, j = end;
        int copy[] = new int[end - start + 1];
        int copy_index = end - start;
        int count = 0;

        while (i >= start && j >= mid + 1) {
            if (array[i] > array[j]) {
                copy[copy_index--] = array[i--];
                count += j - mid;
                if (count > 1000000007)
                    count %= 1000000007;
            } else {
                copy[copy_index--] = array[j--];
            }
        }

        while (i >= start) {
            copy[copy_index--] = array[i--];
        }
        while (j >= mid + 1) {
            copy[copy_index--] = array[j--];
        }
        i = 0;
        while (start <= end) {
            array[start++] = copy[i++];
        }

        return (leftCount + rightCount + count) % 1000000007;
    }
}
输入两个链表,找出它们的第一个公共结点。
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/

import java.util.Stack;
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        ListNode temp = pHead1;
        Stack<ListNode> stack1 = new Stack();
        Stack<ListNode> stack2 = new Stack();

        if (pHead1 == null) return null;
        if (pHead2 == null) return null;

        while (pHead1 != null ) {
            stack1.push(pHead1);
            pHead1 = pHead1.next;
        }
        while (pHead2 != null ) {
            stack2.push(pHead2);
            pHead2 = pHead2.next;
        }
        int pa = 0, pb = 0;
        ListNode result = null;
        while (!stack1.isEmpty() && !stack2.isEmpty()) {
            pa = stack1.peek().val;
            pb = stack2.peek().val;
            if (pa != pb) break;
            result = stack1.pop();
            stack2.pop();
            if (stack1.isEmpty() && stack2.isEmpty())
                return temp;
        }
        return result;
    }
}
统计一个数字在排序数组中出现的次数。
import java.util.Arrays;
public class Solution {
    public int GetNumberOfK(int [] array , int k) {
        if (array == null || array.length == 0) return 0;
        //定义一个数组count[array[lenth-1]]
        int len = array.length;
        int size = array[len - 1];
        Arrays.sort(array);
        int ta = Math.max(len, size) + 10;
        int count[] = new int[ta];
        //出现一次加一次
        for (int i = 0; i < array.length; i++) {
            ++count[array[i]];
        }
        int i;
        for (i = 0; i < array.length; i++) {
            if (k != array[i])
                continue;
            else break;
        }
        if (i == array.length) return 0;
        else return count[k];
    }


}
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
import java.util.ArrayList;
public class Solution {
    public int TreeDepth(TreeNode root) {
        if (root == null) return 0;

        int left =TreeDepth(root.left);
        int right = TreeDepth(root.right);

        if(left>right)return left+1;
        else return right+1;
    }
}
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        if (root == null) return true;

        int left = deepth(root.left);
        int right = deepth(root.right);

        int diff = left - right;
        if (diff > 1 || diff < -1) return false;

        return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }

    static int deepth(TreeNode root) {
        if (root == null) return 0;

        int left = deepth(root.left);
        int right = deepth(root.right);
        if (left > right) return left + 1;
        else return right + 1;
    }
}
一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。请写程序找出这两个只出现一次的数字。
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        Arrays.sort(array);
        int len = array.length;
        int size = Math.max(array.length, array[array.length - 1])+1;

        int count[] = new int[size];
        for (int i = 0; i < array.length; i++) {
            count[array[i]]++;
        }

        for (int i = 0; i < array.length; i++) {
            if (count[array[i]] == 1)
                arrayList.add(array[i]);
        }
        if (arrayList.size() != 0) {
            num1[0] = arrayList.get(0);
            num2[0] = arrayList.get(1);
        }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值