目录
1 二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
public class Solution {
public boolean Find(int target, int [][] array) {
if(array.length == 0 || array[0].length == 0)
return false;
int rows = array.length - 1;
int cols = array[0].length - 1;
int i = 0;
int j = cols;
while(i <= rows && j >= 0)
{
if(array[i][j] < target)
{
i++;
}else if (array[i][j] > target)
{
j--;
}else
{
return true;
}
}
return false;
}
}
2 替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
public class Solution {
public String replaceSpace(StringBuffer str) {
String str1 = str.toString();
if(str1.equals(""))
return str1;
char [] strA = str1.toCharArray();
int i = 0;
int lengthSpace = 0;
while(i < strA.length)
{
if(strA[i] == ' ')
lengthSpace++;
i++;
}
int newSL = strA.length + lengthSpace * 2;
char [] newS = new char[newSL];
int j = newSL - 1;
i = strA.length - 1;
while(i >= 0)
{
if(strA[i] != ' '){
newS[j--] = strA[i--];
}else{
newS[j--] = '0';
newS[j--] = '2';
newS[j--] = '%';
i--;
}
}
return new String(newS);
}
}
3 从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> arrayList = new ArrayList<>();
if(listNode == null)
return arrayList;
printListFromTailToHead(listNode, arrayList);
return arrayList;
}
public void printListFromTailToHead(ListNode listNode, ArrayList<Integer> list){
if(listNode.next != null){
printListFromTailToHead(listNode.next, list);
}
list.add(listNode.val);
}
}
4 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
return BT(pre, 0, pre.length-1, in, 0, in.length-1);
}
public TreeNode BT(int[] pre, int startpre, int endpre, int[] in, int startin, int endin) {
if ((startpre - endpre) > 0 || (startin - endin) > 0) {
return null;
}
TreeNode root = new TreeNode(pre[startpre]);
int rootorder = 0;
for(int i = startin; i <= endin; i++) {
if (in[i] == pre[startpre]) {
rootorder = i;
} else {
System.out.println("error!");
}
}
int leftlength = rootorder - startin;
if (leftlength > 0) {
root.left = BT(pre, startpre + 1, startpre + leftlength, in, startin, rootorder - 1);
}
if ((in.length - leftlength) > 0) {
root.right = BT(pre, startpre + leftlength + 1, endpre, in, rootorder + 1, endin);
}
return root;
}
}
5 用两个栈实现队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if (stack2.empty()) {
while (stack1.empty() != true) {
stack2.push(stack1.pop());
}
}
if (stack2.empty() == true)
return -1;
return stack2.pop();
}
}
6 旋转数组的最小值
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
import java.util.ArrayList;
public class Solution {
public int minNumberInRotateArray(int [] array) {
if (array.length == 0)
return 0;
if (array[0] < array[array.length-1])
return array[0];
int s = 0;
int e = array.length - 1;
int f = 0;
while (s + 1 != e) {
int m = (s + e) / 2;
if (array[m] > array[s])
s = m;
else if (array[m] < array[e])
e = m;
else{
s++;
}
}
return array[e];
}
}
7 牛客网斐波那契数列
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
public class Solution {
public int Fibonacci(int n) {
int a = 0;
int b = 1;
if(n == 0)
return 0;
if(n == 1)
return 1;
int i = 2;
int sum = 0;
while(i <= n){
sum = a + b;
a = b;
b = sum;
i++;
}
return sum;
}
}
8 牛客网跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
public class Solution {
public int JumpFloor(int target) {
if(target == 1)
return 1;
if(target == 2)
return 2;
int a = 1;
int b = 2;
int sum = a + b;
for(int i=3;i<=target;i++)
{
sum = a + b;
a = b;
b = sum;
}
return sum;
}
}
9 牛客网变态跳台阶
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
public class Solution {
public int JumpFloorII(int target) {
return (int)Math.pow(2, target - 1);
}
}
10 矩形覆盖
我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
public class Solution {
public int RectCover(int target) {
if(target == 1)
return 1;
if(target == 2)
return 2;
int a = 1;
int b = 2;
int sum = 0;
for(int i = 3; i <= target; i++) {
sum = a + b;
a = b;
b = sum;
}
return sum;
}
}
11 牛客网二进制中1的个数
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
public class Solution {
public int NumberOf1(int n) {
if (n == 0)
return 0;
int count = 0;
while((n & (n - 1)) != 0) {
count ++;
n = n & (n - 1);
}
count++;
return count;
}
}
12 牛客网数值的整数次方
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
public class Solution {
public double Power(double base, int exponent) {
if(exponent == 0)//指数如果是0
{
if(equalZero(base) == true)//底数是0则返回0
return 0;
return 1;//除了0的任何数的0次方是1
}
if(exponent > 0)//指数大于0
{
return complex(base,exponent);//直接计算base的exponent次方返回即可
}
if(equalZero(base))//底数是0,指数小于0,因为如果指数大于0,在前面已经返回了!
{
if(base > 0)//底数是正0,那么就是正无穷
return Double.POSITIVE_INFINITY;
if(exponent % 2 == 0)//指数是偶数次方
return Double.POSITIVE_INFINITY;//返回正无穷
return Double.NEGATIVE_INFINITY;//其它结果负无穷
}
return 1 / complex(base,exponent);//可以知道除了上述结果,其它都是指数是负数。比如2的-3次方,先计算2的3次方,最后求倒数。
}
double complex(double base,int exponent)
{
double result = 1.0;
if(exponent < 0)//如果指数小于0,比如2的-3次方,先计算2的3次方,然后求倒数
exponent = 0 - exponent;
for(int i=0;i<exponent;i++)
result = result * base;
return result;
}
boolean equalZero(double base)
{//判断一个doule类型的数是不是0,必须这样判断,不能直接与0进行比较,因为浮点数本身不精确
if(base >0 && base < 0.00000001)
return true;
if(base < 0 && base > -0.00000001)
return true;
return false;
}
}
13 调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
import java.util.ArrayList;
public class Solution {
public void reOrderArray(int [] array) {
ArrayList<Integer> odd = new ArrayList<>();
ArrayList<Integer> even = new ArrayList<>();
for(int i = 0; i< array.length; i++) {
if (array[i] % 2 == 1)
odd.add(array[i]);
else
even.add(array[i]);
}
for(int i =0;i<odd.size();i++)
{
array[i] = odd.get(i);//因为奇数数组在前面,所以这样
}
for(int i = 0;i<even.size();i++)
{
array[odd.size()+i] = even.get(i);//把偶数数组赋值到后面
}
}
}
14 链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
int length = 0;
ListNode tempHead = head;
while(tempHead != null)
{
length++;//这里计算链表的长度
tempHead = tempHead.next;
}
if(k > length || k <=0)//因为倒数第K个节点
return null;
ListNode before = head;
ListNode after = head;
for(int i=0;i<k-1;i++) //快指针先走k-1步
before = before.next;
while(before.next != null)
{
before = before.next;
after = after.next;//快慢指针一起走。
}
return after;
}
}
15 反转链表
输入一个链表,反转链表后,输出新链表的表头。
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode p = head.next;//p指向头结点的下一个节点
ListNode pre = head;//p节点的前一个节点pre.
pre.next = null;//先把第一个节点当做最后一个节点,置位null
ListNode next = p.next;//然后next记录p的下一个节点
while(p != null)
{
p.next = pre;//p当前节点指向前一个pre,完成这两个节点的反转
pre = p;//然后pre往后移动
p = next;//然后p指向next 这样都开始往后移动了。
if(p != null)//只要下一个节点不为空,next才可以赋值成下一个节点。
next = p.next;
}
head = pre;
return head;
}
}
16 合并两个排序的列表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode resultList = new ListNode(0);//新建一个头结点
ListNode tempHead = resultList;
while(list1 != null && list2 != null)//直到有一个链表先为空,那么结束
{
if(list1.val < list2.val)//哪个小那么tempHead的这个下一个节点就是哪个
{
tempHead.next = list1;
list1 = list1.next;
}else{
tempHead.next = list2;
list2 = list2.next;
}
tempHead = tempHead.next;//遍历的tempHead指向下一个。
}
if(list1 == null)//如果链表1为空,那么链表可能不为空
{
tempHead.next = list2;//所以把链表2接到后面
}else{
tempHead.next = list1;//否则说明链表2为空,把链表1接到后面
}
return resultList.next;//返回头结点的下一个
}
}
17 树的子结构
输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root2 == null || root1 == null)//当Tree1和Tree2都不为零的时候,才进行比较。否则直接返回false
return false;
boolean flag = false;
if(root1.val == root2.val)//以这个根节点为为起点判断是否包含Tree2
{
flag = doHasSubtree(root1,root2);
}
if(flag)
return flag;
if(!flag)
{//如果找不到,那么就再去root的左儿子当作起点,去判断时候包含Tree2
flag = HasSubtree(root1.left,root2);
if(flag)
return true;
else{//如果还找不到,那么就再去root的右儿子当作起点,去判断时候包含Tree2
flag = HasSubtree(root1.right,root2);
if(flag)
return true;
}
}
return false;
}
private boolean doHasSubtree(TreeNode root1,TreeNode root2)
{
if(root2 == null)//如果Tree2已经遍历完了都能对应的上,返回true
return true;
if(root1 == null)//如果Tree2还没有遍历完,Tree1却遍历完了。返回false
return false;
if(root1.val != root2.val)//如果其中有一个点没有对应上,返回false
return false;
//如果根节点对应的上,那么就分别去子节点里面匹配
return doHasSubtree(root1.left,root2.left) && doHasSubtree(root1.right,root2.right);
}
}
18 二叉树的镜像
操作给定的二叉树,将其变换为源二叉树的镜像。
public class Solution {
public void Mirror(TreeNode root) {
if(root == null )
return;
if(root.left == null && root.right == null)
return;
TreeNode tempNode = root.right;
root.right = root.left;
root.left = tempNode; //这里三行代码进行 交换左右子树
Mirror(root.left);//对于左子树 递归调用 就是说对于左子树也进行交换
Mirror(root.right);//右子树同理
}
}
19 顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> result = new ArrayList<>();
int cols = matrix[0].length;
int rows = matrix.length;
int left = 0, top = 0, right = cols - 1, bottom = rows - 1;
int count = 0;
while(count < cols*rows) {
for(int i = left; i <= right; i++) {
result.add(matrix[top][i]);
count++;
if(count >= cols*rows)
return result;
}
top++;
for(int i = top; i <= bottom; i++) {
result.add(matrix[i][right]);
count++;
if(count >= cols*rows)
return result;
}
right--;
for(int i = right; i >= left; i--) {
result.add(matrix[bottom][i]);
count++;
if(count >= cols*rows)
return result;
}
bottom--;
for(int i = bottom; i >= top; i--) {
result.add(matrix[i][left]);
count++;
if(count >= cols*rows)
return result;
}
left++;
}
return result;
}
}
20 包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
import java.util.Stack;
public class Solution {
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
public void push(int node) {
stack1.push(node);
if(stack2.empty()) {
stack2.push(node);
} else {
if (node <= (int)stack2.peek())
stack2.push(node);
else
stack2.push(stack2.peek());
}
}
public void pop() {
stack2.pop();
stack1.pop();
}
public int top() {
return (int) stack1.peek();
}
public int min() {
return (int) stack2.peek();
}
}
21 栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
import java.util.*;
public class Solution {
public boolean IsPopOrder(int [] pushA,int [] popA) {
if(pushA.length != popA.length)
return false;
Stack<Integer> stack1 = new Stack<>();//栈记录压栈
int j = 1;
stack1.push(pushA[0]);//栈中先压入push压栈序列的第一个数
for(int i=0;i<popA.length;i++)
{
while(j < pushA.length && stack1.peek() != popA[i])
{//如果栈顶的数和弹出序列不一样,就一直压栈,因为必须是从栈顶弹出的!
stack1.push(pushA[j]);
j++;
}
if(j >= pushA.length && stack1.peek() != popA[i])
return false;//如果j已经到达压栈序列的末尾,但是栈顶的数还是和弹出序列当前的数不一致
//说明没有这个序列
stack1.pop();
}
return true;
}
}
22 从上往下打印二叉树
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> resultList = new ArrayList<>();
if(root == null)
return resultList;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(queue.size() != 0)//队列不为空一直进行
{
TreeNode tempRoot = queue.poll();//出队
if(tempRoot.left != null)//左子节点不为空,左子节点入队
queue.offer(tempRoot.left);
if(tempRoot.right != null)//右子节点不为空,右子节点入队
queue.offer(tempRoot.right);
resultList.add(tempRoot.val);//把出队的节点的值保留下来
}
return resultList;
}
}
23 二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。https://blog.youkuaiyun.com/Heloiselt/article/details/80227473
public class Solution {
public boolean VerifySquenceOfBST(int [] sequence) {
if (sequence.length == 0)
return false;
return verify(sequence, 0, sequence.length - 1);
}
public boolean verify(int[] sequence, int begin, int end) {
if (begin == end)
return true;
int rootValue = sequence[end];
int leftBegin = -1;
int leftEnd = -1;
int rightBegin = -1;
int rightEnd = -1;
if(sequence[begin] < rootValue)
leftBegin = begin;
for(int i = begin; i < end; i++) {
if(sequence[i] < rootValue)
leftEnd = i;
else{
if(rightBegin == -1)
rightBegin = i;
rightEnd = i;
}
}
if (rightBegin < leftEnd && rightBegin != -1)
return false;
return verify(sequence,leftBegin,leftEnd) && verify(sequence,rightBegin,rightEnd);
}
}
24 二叉树中和为某一值的路径
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
import java.util.ArrayList;
/*
//TreeNode也可以写成内部类
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {
ArrayList<ArrayList<Integer>> arrlist = new ArrayList<ArrayList<Integer>>();
if(root == null) return arrlist;
ArrayList<Integer> a1 = new ArrayList<Integer>();
int sum = 0;
sums(root, target, arrlist,a1, sum);
return arrlist;
}
public void sums(TreeNode root, int target, ArrayList<ArrayList<Integer>> arrlist, ArrayList<Integer> a1, int sum){
if(root == null) return;
sum = sum + root.val;
if(root.left == null && root.right == null){
if(sum == target){
a1.add(root.val);
arrlist.add(new ArrayList<Integer>(a1));
//
a1.remove(a1.size()-1);
}
return;
}
a1.add(root.val);
sums(root.left, target, arrlist,a1, sum);
sums(root.right, target, arrlist,a1, sum);
a1.remove(a1.size()-1);
}
}
25 复杂链表的复制
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
import java.util.HashMap;
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone (RandomListNode pHead){
if(pHead == null){
return null;
}
HashMap<RandomListNode, RandomListNode> map = new HashMap();
RandomListNode p = pHead;
while (p != null){
RandomListNode cp = new RandomListNode(p.label);
map.put(p, cp);
p = p.next;
}
//link
p = pHead;
while (p != null){
RandomListNode cp = map.get(p);
cp.next = (p.next == null) ? null : map.get(p.next);
cp.random = (p.random == null) ? null : map.get(p.random);
p = p.next;
}
return map.get(pHead);
}
}
26 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
import java.util.ArrayList;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null || (pRootOfTree.left == null && pRootOfTree.right == null))
return pRootOfTree;
ArrayList<TreeNode> nodeList = new ArrayList<>();
BuildArrayList(pRootOfTree,nodeList);//这个函数执行后,数组中每个元素按照大小前后排序
for(int i=0;i<nodeList.size();i++)
{
if(i == 0)
{//数组的第一个节点处理,只有右子树指向下一个节点
nodeList.get(0).right = nodeList.get(1);
}
else if(i == nodeList.size()-1)
{//数组的最后一个节点,只有左子树指向前一个节点
nodeList.get(i).left = nodeList.get(i-1);
}
else{//数组中的中间节点,左子树指向上一个节点,右子树指向数组的下一个节点
nodeList.get(i).left = nodeList.get(i-1);
nodeList.get(i).right = nodeList.get(i+1);
}
}
return nodeList.get(0);
}
public void BuildArrayList(TreeNode root,ArrayList<TreeNode> nodeList)
{//二叉搜索的中序遍历,并把每个节点存入数组中
if(root == null)
return;
if(root.left != null)//左子树
BuildArrayList(root.left,nodeList);
if(root != null)//根节点
nodeList.add(root);
if(root.right != null)//右子树
BuildArrayList(root.right,nodeList);
}
}
27 字符串的排列
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
import java.util.ArrayList;
import java.util.TreeSet;
public class Solution {
ArrayList<String> result = new ArrayList<>();
TreeSet<String> set = new TreeSet<>();//使用一个TreeSet保证有序和无重复
public ArrayList<String> Permutation(String str) {
char [] strArray = str.toCharArray();
Permutation(strArray,0);
while(set.isEmpty() != true)
result.add(set.pollFirst());
return result;
}
public void Permutation(char [] strArray,int index)
{
if(index == strArray.length - 1)
{//这里的话就是每当到了最后一个字符的时候,就添加一个字符串
set.add(String.valueOf(strArray));
}else{
for(int i=index;i<strArray.length;i++)
{
swap(strArray,index,i);
Permutation(strArray,index+1);
swap(strArray,index,i);
}
}
}
public void swap(char [] strArray,int i,int j)
{
char ch = strArray[i];
strArray[i] = strArray[j];
strArray[j] = ch;
}
}
28 数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array.length == 0)
return 0;
int count = 1;
int number = array[0];
for(int i=1;i<array.length;i++)
{
if(array[i] == number)
{//如果与number相等,那么count++,可能是超过一半的那个数
count++;
}else{
count--;//如果与number不相等,count就减一
if(count == 0)
{//如果count等于0了,说明这个数在这里出现次数已经被抵消了
count = 1;//重新记录count为1
number = array[i];//number记录当前这个数
}
}
}
if(count > 0)
{//如果count大于0说明有可能存在这样的数,是出现次数大于数组的一半的
//还有一种可能是最后刚好一个数连续出现了2次,导致count>0
count = 0;
for(int i=0;i<array.length;i++)
{//去遍历数组,计数这个number到底出现了几次
if(number == array[i])
count++;
}
if(count > array.length/2)
return number;//出现超过一半
}
return 0;
}
}
29 最小的K个数
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
import java.util.*;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> resultList = new ArrayList<>();
if(k > input.length || k<=0)
return resultList;
//使用优先级队列建堆,优先级队列默认是最小堆,所以要重写比较器
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(new Comparator<Integer>(){
public int compare(Integer o1,Integer o2){
return o2.compareTo(o1);
}
}
);
for(int i=0;i<input.length;i++)
{
if(i < k){//如果没有达到k个数,那么直接入堆
maxHeap.add(input[i]);
}else{
if(maxHeap.peek() > input[i])
{//堆顶的数比数组当前的数大,那么就堆顶出堆
maxHeap.poll();
maxHeap.add(input[i]);//把当前数加入堆中
}
}
}
while(maxHeap.isEmpty() != true)
resultList.add(maxHeap.poll());//把堆中的数出堆添加到结果数组中
return resultList;
}
}
30 连续子数组的最大和
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
import java.util.*;
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
if(array.length <= 0)
return -1;
int realMax = array[0];
int currentMax = 0;//当前最大值
for(int i=0;i<array.length;i++)
{
if(currentMax + array[i] >= array[i])
{//当前最大值加上当前数组的数如果比数组当前这个数大,那么就累加
//这里得好好体会,因为前面连续和大于0,所以加上当前数连续和肯定变大!所以是可能的最大连续和
currentMax += array[i];
}else{
//如果当前连续最大和小于0,那么就把currentMax赋值为当前这个数组中的数,重新开始
currentMax = array[i];
}
if(currentMax > realMax)//每计算出一个当前最大连续和就和最后的要返回结果进行比较
realMax = currentMax;//更新
}
return realMax;
}
}
31 整数中1出现的次数
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
if (n < 1)
return 0;
int count = 0;
int base = 1;
int round = n;
while (round > 0) {
int weight = round % 10; //round的最后一位数,从个位数开始
round /= 10;
count += round * base;
if (weight == 1)
count += (n % base) + 1;
else if (weight > 1)
count += base;
base *= 10;
}
return count;
}
}
32 把数组排成最小的数
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
import java.util.*;
public class Solution {
public String PrintMinNumber(int [] numbers) {
if(numbers.length == 0)
return "";
TreeSet<String> set = new TreeSet<>();
PrintMinNumber(numbers,0,set);
return set.pollFirst();
}
public void PrintMinNumber(int [] numbers,int index,TreeSet<String> set)
{
if(index == numbers.length-1)
{
String tempStr = "";
for(int i=0;i<numbers.length;i++)
tempStr += String.valueOf(numbers[i]);
set.add(tempStr);
}else{
for(int i=index;i<numbers.length;i++)
{
swap(numbers,index,i);
PrintMinNumber(numbers,index+1,set);
swap(numbers,index,i);
}
}
}
public void swap(int [] numbers,int i,int j)
{
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
33 丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
import java.util.*;
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index <= 0)
return 0;
if(index == 1)
return 1;
ArrayList<Integer> resultList = new ArrayList<>();
resultList.add(1);
int index2=0,index3=0,index5=0;
int count = 1;
while(count < index)
{
int next = min(resultList.get(index2)*2,resultList.get(index3)*3,resultList.get(index5)*5);
resultList.add(next);
count++;
while(resultList.get(index2)*2 <= next)
index2++;//每次都往后进行更新,找到当前如果因子为2最大的index2
while(resultList.get(index3)*3 <= next)
index3++;//同理
while(resultList.get(index5)*5 <= next)
index5++;//同理
}
return resultList.get(index-1);
}
public int min(int a,int b,int c)
{
int temp = (a<b)?a:b;
return (temp<c)?temp:c;
}
}