剑指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);
}
}
}