数组中出现次数超过一半的数字
题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
public class Solution
{
/**
*
采用阵地攻守的思想: 第一个数字作为第一个士兵,守阵地;count = 1;
*
遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count--;
*
当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,
*
有可能是主元素。 再加一次循环,记录这个士兵的个数看是否大于数组一般即可。
*
@param array
*
@return
*/
public int MoreThanHalfNum_Solution(int[]
array) {
int length
= array.length;
if (array
== null ||
length <= 0)
{
return 0;
}
int result
= array[0];
int times
= 1;
for (int i
= 1;
i < length; i++) {
if (times
== 0)
{
result = array[i];
times = 1;
} else {
if (array[i]
== result) {
times++;
} else {
times--;
}
}
}
times = 0;
for (int i
= 0;
i < length; i++) {
if (result
== array[i]) {
times++;
}
}
if (times
* 2 <
length) {
result = 0;
}
return result;
}
} |
最小的K个数
题目描述:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
import java.util.ArrayList;
public class Solution
{
/**
*
最小的K个数
*
@param input
*
@param k
*
@return
*/
public ArrayList<Integer>
GetLeastNumbers_Solution(int[]
input, int k)
{
ArrayList<Integer> aList
= new ArrayList<Integer>();
if (input.length
< k || input == null)
{
return aList;
}
if (k
== 0)
{
return aList;
}
int len
= input.length;
findSort(input, 0,
len - 1,
k);
for(int i=0;i<k;i++){
aList.add(input[i]);
}
return aList;
}
/*
递归查找
*/
private
void findSort(int[] input, int p, int r, int k) {
if
(p == r) {
return;
}
int
q = partition(input, p, r);
int
temp = q - p + 1;///当前的长度
if
(temp == k) {
return;
}
else if (k < temp) {
findSort(input,
p, q - 1, k);
}
else {
findSort(input,
q + 1, r, k - temp);
}
}
/* 分治法来实现最小k的查找/*
*/
private int partition(int[]
input, int p, int q)
{
int x
= input[q];
int i
= p - 1;
for (int j
= p; j < q ; j++) {
if (input[j]
<= x) {
i = i + 1;
int temp
= input[i];
input[i] = input[j];
input[j] = temp;
}
}
input[q] = input[i + 1];
input[i + 1]
= x;
return i
+ 1;
}
} |
连续子数组的最大和
题目描述:HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
public class Solution
{
/*
分治法求解最大字数组
这个算法自己曾经实现过 不过有些问题没有解决
*/
public int FindGreatestSumOfSubArray(int[]
array) {
if (array.length
== 0 ||
array == null)
{
return 0;
}
int result
= findMaxSubArray(array, 0,
array.length - 1);
return result;
}
private int findMaxSubArray(int[]
arr, int left, int right)
{
int result=0;
if (left
== right) {
result=arr[left];
return result;
} else {
int mid
= (left + right) / 2;
int saleft
= findMaxSubArray(arr, left, mid);
int saright
= findMaxSubArray(arr, mid+1,
right);
int sacross
= findCrossingMaxSubArray(arr, left, mid,
right);
if (saleft
> saright
&&
saleft > sacross) {
return saleft;
} else if (saright
> saleft
&&
saright > sacross) {
return saright;
} else {
return sacross;
}
}
}
private int findCrossingMaxSubArray(int[]
arr, int left, int mid, int right)
{
int sum=0;
int begin=0;
int end=0;
int leftsum
= arr[mid] ;
sum=arr[mid];
for(int i=mid-1;i>=left;i--){
sum=sum+arr[i];
if(sum>leftsum){
leftsum=sum;
begin=i;
}
}
int rightsum
= arr[mid+1];
sum=arr[mid+1];
for(int i=mid+2;i<=right;i++){
sum=sum+arr[i];
if(sum>rightsum){
rightsum=sum;
end=i;
}
}
return leftsum+rightsum;
}
} |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Solution
{
public static int FindGreatestSumOfSubArray(int[]
array) {
if(array.length==0) return 0;
int sum
= 0 ,result
= array[0];
for (int i
= 0;
i < array.length; i++) {
if(sum<0)
sum
= array[i];
else
sum
+= array[i];
result
= Math.max(result, sum);
}
return result;
}
} |
题目描述:求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
把数组排成最小的数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
public class Solution
{
public int NumberOf1Between1AndN_Solution(int n)
{
if(n<=0){
return 0;
}
String
str = Integer.toString(n);
char[]
strN=str.toCharArray();
return NumberOf1(strN,0);
}
private int NumberOf1(char[]
strN,int loc)
{
if(strN==null||strN[loc]<'0'||strN[loc]>'9'||strN[loc]=='\0'){
return 0;
}
int first=strN[loc]-'0';
//剩余长度
int len
= strN.length-loc;//剩余 长度 下标是从0开始
if(len==1&&first==0){
return 0;
}
if(len==1&&first>0){
return 1;
}
int numFirstDigit=0;
if(first>1){
numFirstDigit=PowerBase10(len-1);
}else if(first==1){
numFirstDigit=Atoi(strN,loc+1)+1;//将后序的字符转换成为数值
}
//除了开头第一位的所有其他的四位数中的情况
int numOtherDigit=first*(len-1)*PowerBase10(len-2);
int numRecursive
= NumberOf1(strN, loc+1);
return numFirstDigit+numOtherDigit+numRecursive;
}
private int Atoi(char[]
strN, int loc)
{
int num
= 0;
for(int i=loc;i<strN.length;i++){
num=num*10+(strN[i]-'0');
}
return num;
}
private int PowerBase10(int n)
{
int res=1;
for(int i=0;i<n;i++){
res*=10;
}
return res;
}
} |
题目描述:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
import java.util.ArrayList;
public class Solution
{
/**
*
生成最小数值的数组排列 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
*
例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
*
*
@param numbers
*
@return
*
*
这个题目主要是想找到一个排序规则,数组根据这个排序规则来排成一个最小的数字。要确定排序规则就要比较两个数字,也就是比较
*
m和n,我们需要一个规则判断m和n哪一个应该排在前面,而不是仅仅比较两个数字的值哪个更大。
*
*
根据题目要求,两个数字m和n 拼接成为mn和nm如果mn小于nm,那么我们应该打印出mn,也就是m应该排在n 的前面。
*
我们定义此时m<n.这是我们自定义的大小比较关系。
*
*
拼接称为字符串,按照字符串比较大小就可以了。
*/
public String
PrintMinNumber(int[]
numbers) {
if (numbers.length
== 0 ||
numbers == null)
{
return "";
}
int len
= numbers.length;
String[]
strNums = new String[len];
for (int i
= 0;
i < len; i++) {
strNums[i]
= Integer.toString(numbers[i]);
//
construct string from a int array
}
String
res = qSortStrArray(strNums, len);
return res;
}
private String
qSortStrArray(String[] strNums, int len)
{
if (strNums
== null ||
strNums.length == 0)
return null;
for(int i=0;i<len-1;i++){
for(int j=i;j<len;j++){
if((strNums[i]+strNums[j]).compareTo(strNums[j]+strNums[i])>0){
String
temp = strNums[i];
strNums[i]=strNums[j];
strNums[j]=temp;
}
}
}
String
res="";
for(int i=0;i<len;i++){
res+=strNums[i];
}
return res;
}
} |