面试题目汇总(JAVA算法/数据结构)

1.题目:输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

代码:

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.Iterator;

public class Solution {

    public static String PrintMinNumber(int [] numbers) {

String result = "";

int length=numbers.length;

if(length<1){

return result;

}

ArrayList<Integer> list=new ArrayList<Integer>();

for(int i=0;i<length;i++){

list.add(numbers[i]);

}

Collections.sort(list,new Comparator<Integer>() {

@Override

public int compare(Integer o1, Integer o2) {

String result1=o1+""+o2;

String result2=o2+""+o1;

return result1.compareTo(result2);

}

});

Iterator<Integer> iterator=list.iterator();

while(iterator.hasNext()){

result+=(iterator.next()+"");

}

return result;

    }

}

2.题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

代码:

/**

 * Definition for binary tree

 * public class TreeNode {

 *     int val;

 *     TreeNode left;

 *     TreeNode right;

 *     TreeNode(int x) { val = x; }

 * }

 */

public class Solution {

    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {

return DFS(pre,in,0,pre.length-1,0,in.length-1);

}

private TreeNode DFS(int []pre,int []in,int prestart,int preend,int instart,int endstart){

if(prestart>preend||instart>endstart){

return null;

}

TreeNode root=new TreeNode(pre[prestart]);

for(int indexstart=instart;indexstart<=endstart;indexstart++){

if(pre[prestart]==in[indexstart]){

root.left=DFS(pre, in, prestart+1, prestart+indexstart-instart, instart, indexstart-1);

root.right=DFS(pre, in, indexstart-instart+prestart+1, preend, indexstart+1, endstart);

}

}

return root;

}

}

3.题目:给定一颗二叉搜索树,请找出其中的第k大的结点。例如, 5 / \ 3 7 /\ /\ 2 4 6 8 中,按结点数值大小顺序第三个结点的值为4。

代码:

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}

*/

import java.util.ArrayList;

import java.util.Arrays;

import java.util.Collections;

import java.util.Comparator;

import java.util.Iterator;

public class Solution {

    //思路:二叉搜索树的中序遍历就是按顺序排列的,所以,直接中序查找就可以了

   int index=0;

TreeNode KthNode(TreeNode pRoot, int k) {

if(pRoot!=null){

TreeNode left=KthNode(pRoot.left, k);

if(left!=null)

return left;

index++;

if(index==k)

return pRoot;

TreeNode right=KthNode(pRoot.right, k);

if(right!=null)

return right;

}

return null;

     }

}

题目描述

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)

代码:

public class Solution {

public int FindGreatestSumOfSubArray(int[] array) {

if(array.length==0){

return 0;

}

int sum=array[0];

int Maxsum=array[0];

for(int i=1;i<array.length;i++){

if(sum<0){

sum=0;

}

sum+=array[i];

Maxsum=Math.max(Maxsum, sum);

}

return Maxsum;

}

}

题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

代码:

import java.util.HashSet;

import java.util.Iterator;

import java.util.LinkedHashSet;

import java.util.Set;

public class Solution {

    // Parameters:

    //    numbers:     an array of integers

    //    length:      the length of array numbers

    //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;

    //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++

    //    这里要特别注意~返回任意重复的一个,赋值duplication[0]

    // Return value:       true if the input is valid, and there are some duplications in the array number

    //                     otherwise false

    // private static final int Max=(int) (1e5+10);

private static int []vis;

public static boolean duplicate(int numbers[], int length, int[] duplication) {

if(length<1){

return false;

}

vis=new int [length];

for(int i=0;i<length;i++){

vis[numbers[i]]++;

}

Set<Integer> set=new HashSet<Integer>();

for(int i=0;i<length;i++){

if(vis[numbers[i]]>1){

set.add(numbers[i]);

}

}

Iterator<Integer> iterator=set.iterator();

int cnt=0;

while(iterator.hasNext()){

duplication[cnt++]=iterator.next();

break;

}

// for(int i=0;i<cnt;i++){

// System.out.print(duplication[i]+" ");

// }

if(cnt!=0){

return true;

}

return false;

}

}

题目描述

LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何。为了方便起见,你可以认为大小王是0。

代码:

import java.util.HashSet;

import java.util.Set;

public class Solution {

    //思路:判断不合法的情况:1.numbers长度不为5,2.numbers中除0外,有重复的数,3.最大值减最小值>=5

//剩下的就是合法的情况了

   public boolean isContinuous(int[] numbers) {

int length=numbers.length;

if(length!=5){

return false;

}

Set<Integer> hashSet=new HashSet<Integer>();

int ans=0;//0的个数

int Max=-1,Min=100;

for(int i=0;i<length;i++){

if(numbers[i]!=0){

hashSet.add(numbers[i]);

Max=Math.max(Max, numbers[i]);

Min=Math.min(Min, numbers[i]);

}else{

ans++;

}

}

if(ans+hashSet.size()!=length){

return false;

}

if(Max-Min>=5){

return false;

}

return true;

}

}

题目描述

汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

代码:

public class Solution {

 public  String LeftRotateString(String str, int n) {

if(str.length()==0){

return str;

}

n%=(str.length());

if(str.length()<1)

return null;

for(int i=0;i<n;i++)

str=GetString(str);

return str;

}

private  String GetString(String str){

return str.substring(1, str.length())+str.charAt(0);

}

}

题目描述

牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

代码:

public class Solution {

 public static String ReverseSentence(String str) {

String string=str.trim();

String a="";

if(string.equals(a)){

return str;

}

StringBuilder result=new StringBuilder();

String []split=str.split(" ");

for(int i=split.length-1;i>=0;i--){

result.append((split[i]+" "));

}

return result.toString().trim();

}

}

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

代码:

import java.util.ArrayList;

public class Solution {

   public static ArrayList<Integer> maxInWindows(int [] num, int size)

    {

        ArrayList<Integer> list=new ArrayList<Integer>();

        int length=num.length;

        if(size<=0){

        return list;

        }

        if(length>=1){

        int Max=Integer.MIN_VALUE;

        for(int i=0;i<length;i++){

        Max=Math.max(Max, num[i]);

        }

        if(size>length){

        return list;

        }else{

        for(int i=0;i<length-size+1;i++){

        int MAX=Integer.MIN_VALUE;

        for(int j=i;j<size+i;j++){

        MAX=Math.max(MAX, num[j]);

        }

        list.add(MAX);

        }

        }

        }

        return list;

    }

}

题目描述

每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

代码:

public class Solution {

    private final static int Max=(int) (1e5+10);

public int LastRemaining_Solution(int n, int m) {

int []array=new int[Max];

int i=-1,count=n,step=0;

while(count>0){//模拟环

i++;

if(i>=n){

i=0;

}

if(array[i]==-1)

continue;

step++;

if(step==m){

step=0;

count--;

array[i]=-1;

}

}

return i;

}

}

题目描述

请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

代码:

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<ArrayList<Integer>> Print(TreeNode pRoot) {

ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();

if(pRoot==null){

return list;

}

int ans=1;

Queue<TreeNode> queue=new LinkedList<TreeNode>();

queue.add(pRoot);

while(!queue.isEmpty()){

ArrayList<Integer> nodes=new ArrayList<Integer>();

int size=queue.size();

for(int i=0;i<size;i++){

TreeNode root=queue.poll();

if(ans%2==0){

nodes.add(0,root.val);

}else{

nodes.add(root.val);

}

if(root.left!=null){

queue.add(root.left);

}

if(root.right!=null){

queue.add(root.right);

}

}

list.add(nodes);

ans++;

}

return list;

}

}

题目描述

从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

代码:

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}

*/

import java.util.ArrayList;

import java.util.LinkedList;

import java.util.Queue;

public class Solution {

    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {

    ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();

    if(pRoot==null){

    return list;

    }

    Queue<TreeNode> queue=new LinkedList<TreeNode>();

    queue.add(pRoot);

    while(!queue.isEmpty()){

    ArrayList<Integer> arrayList=new ArrayList<Integer>();

    int size=queue.size();

    for(int i=0;i<size;i++){

    TreeNode root=queue.poll();

    arrayList.add(root.val);

    if(root.left!=null){

    queue.add(root.left);

    }

    if(root.right!=null){

    queue.add(root.right);

    }

    }

    list.add(arrayList);

    }

    return list;

    }

    

}

题目描述

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

代码:

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

public class Solution {

    private ArrayList<Integer> list=new ArrayList<Integer>();

public void Insert(Integer num) {

list.add(num);

Collections.sort(list,new Comparator<Integer>() {

@Override

public int compare(Integer o1, Integer o2) {

return o1-o2;

}

});

}

public Double GetMedian() {

int length=list.size();

int MID=length>>1;

double mid=0;

if((length&1)==0){

Integer a1=list.get(MID);

Integer a2=list.get(MID-1);

mid=(Double.valueOf(a1+"")+Double.valueOf(a2+""))/2;

}else{

Integer a3=list.get(MID);

mid=Double.valueOf(a3+"");

}

return mid;

}

}

题目描述

小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck! 

输出描述:

输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序

代码:

import java.util.ArrayList;

public class Solution {

    public static ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {

ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();

if (sum < 0) {

return list;

}

for (int i = 1; i <= sum; i++) {

for (int j = i; j <= sum; j++) {

int n = j - i + 1;

int ans = i*n+(n*(n-1))/2;

if (ans != sum) {

continue;

}

ArrayList<Integer> arrayList = new ArrayList<>();

for (int k = i; k <= j; k++) {

arrayList.add(k);

}

if(arrayList.size()>=2){//至少包括两个数

list.add(arrayList);

}

}

}

return list;

}

}

题目描述

有一副由NxN矩阵表示的图像,这里每个像素用一个int表示,请编写一个算法,在不占用额外内存空间的情况下(即不使用缓存矩阵),将图像顺时针旋转90度。

给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于500,图像元素小于等于256。

测试样例:

[[1,2,3],[4,5,6],[7,8,9]],3

返回:[[7,4,1],[8,5,2],[9,6,3]]

代码:

import java.util.*;

public class Transform {

    public  int[][] transformImage(int[][] mat, int n) {

int [][]A=new int[n][n];

int x=0,y=n-1;

for(int i=0;i<n;i++){

for(int j=0;j<n;j++){

A[x][y]=mat[i][j];

if(x==n-1){

y--;

x=0;

}else{

x++;

}

}

}

return A;

    }

}

题目描述

假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。

给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。

测试样例:

"Hello world","worldhello "

返回:false

"waterbottle","erbottlewat"

返回:true

代码:

import java.util.*;

public class ReverseEqual {

    public boolean checkReverseEqual(String s1, String s2) {

if(s1==null||s2==null||s1.length()!=s2.length()){

return false;

}

return (s1+s1).contains(s2);

}

}

题目描述

输入一个链表,输出该链表中倒数第k个结点。

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

import java.util.LinkedHashMap;

public class Solution {

public ListNode FindKthToTail(ListNode head, int k) {

LinkedHashMap<Integer, ListNode> map=new LinkedHashMap<Integer, ListNode>();

int cnt=0;

while(head!=null){

map.put(cnt++, head);

head=head.next;

}

return map.get(cnt-k);

}

}

题目描述

实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。

给定带删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true

代码:

import java.util.*;

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

public class Remove {

    public boolean removeNode(ListNode pNode) {

        if(pNode==null){

return false;

}

if(pNode.next==null){

return false;

}

return true;

    }

}

题目描述

编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前

给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以后保持原来的数据顺序不变。

代码:

import java.util.*;

import java.util.Collections;

import java.util.Comparator;

import java.util.LinkedList;

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

public class Partition {

 public ListNode partition(ListNode pHead, int x) {

if(pHead==null||pHead.next==null){

return pHead;

}

ListNode cur=pHead;

ListNode Ahead=new ListNode(-1);

ListNode Bhead=new ListNode(-1);

ListNode Atemp=Ahead;

ListNode Btemp=Bhead;

while(cur!=null){

if(cur.val<x){

Atemp.next=new ListNode(cur.val);

Atemp=Atemp.next;

}else{

Btemp.next=new ListNode(cur.val);

Btemp=Btemp.next;

}

cur=cur.next;

}

ListNode newhead=Ahead;

while(newhead.next!=null&&newhead.next.val!=-1){

newhead=newhead.next;

}

newhead.next=Bhead.next;

return Ahead.next;//取Ahead->next而不取Ahead是因为Ahead头的val是-1,不是链表中的值

}

}

题目描述

有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。

给定两个链表ListNode* A,ListNode* B,请返回A+B的结果(ListNode*)。

测试样例:

{1,2,3},{3,2,1}

返回:{4,4,4}

代码:

import java.util.*;

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

public class Plus {

  public static ListNode plusAB(ListNode a, ListNode b) {

if (a == null && b == null) {

return null;

}

ListNode Ahead = a;

ListNode Bhead = b;

ListNode newhead = new ListNode(-1);

ListNode newtemp = newhead;

int temp = 0;

while (Ahead != null || Bhead != null) {

// 三种情况:1:Ahead!=null&&Bhead!=null

// 2:Ahead==null&&Bhead!=null

// 3:Ahead!=null&&Bhead==null

if (Ahead != null && Bhead != null) {

ListNode node = new ListNode((Ahead.val + Bhead.val + temp) % 10);

temp = (Ahead.val + Bhead.val + temp) / 10;

newtemp.next = node;

newtemp = newtemp.next;

Ahead = Ahead.next;

Bhead = Bhead.next;

} else if (Ahead == null && Bhead != null) {

ListNode node = new ListNode((Bhead.val + temp) % 10);

temp = (Bhead.val + temp) / 10;

newtemp.next = node;

newtemp = newtemp.next;

Bhead = Bhead.next;

} else if (Ahead != null && Bhead == null) {

ListNode node = new ListNode((Ahead.val + temp) % 10);

temp = (Ahead.val + temp) / 10;

newtemp.next = node;

newtemp = newtemp.next;

Ahead = Ahead.next;

}

}

if (temp != 0) {

ListNode node = new ListNode(temp);

newtemp.next = node;

newtemp = newtemp.next;

}

return newhead.next;

}

}

题目描述

输入一个链表,反转链表后,输出链表的所有元素。

代码:

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

import java.util.LinkedHashMap;

public class Solution {

    public ListNode ReverseList(ListNode head) {

       if(head==null){

       return null;

       }

       ListNode newhead=null;

       ListNode phead=head;

       ListNode prehead=null;

       while(phead!=null){

       ListNode pnext=phead.next;

       if(pnext==null){

       newhead=phead;

       }

       phead.next=prehead;

       prehead=phead;

       phead=pnext;

       }

       return newhead;

    }

}

题目描述

请编写一个函数,检查链表是否为回文。

给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。

测试样例:

{1,2,3,2,1}

返回:true

{1,2,3,2,3}

返回:false

代码:

import java.util.*;

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

public class Palindrome {

   public boolean isPalindrome(ListNode pHead) {

if (pHead == null) {

return false;

}

LinkedList<Integer> linkedList = new LinkedList<Integer>();

while (pHead != null) {

linkedList.add(pHead.val);

pHead = pHead.next;

}

return Check(linkedList);

}

// 检查是否为回文串

private boolean Check(LinkedList<Integer> linkedList) {

boolean result = true;

int len = linkedList.size();

int length =len>>1;

for (int i = 0; i < length; i++) {

if (linkedList.get(i) != linkedList.get(len - i - 1)) {

result = false;

break;

}

}

return result;

}

}

题目描述

用两个栈来实现一个队列,完成队列的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() {

    while(!stack1.isEmpty()){

    stack2.push(stack1.pop());

    }

    int node=stack2.pop();

    while(!stack2.isEmpty()){

    stack1.push(stack2.pop());

    }

    return node;

    }

}

题目描述

有一些数的素因子只有3、5、7,请设计一个算法,找出其中的第k个数。

给定一个数int k,请返回第k个数。保证k小于等于100。

测试样例:

3

返回:7

代码:

import java.util.*;

public class KthNumber {

   private static final int Max = (int) (1e5 + 10);

private static int cnt;

private static int []A;

public static int findKth(int k) {

InitData();

return A[k];

}

private static void InitData() {

cnt=1;

int a=0,b=0,c=0;

A=new int[Max];

A[0]=1;

while(cnt<=100){

int temp=Math.min(A[a]*3, Math.min(A[b]*5, A[c]*7));

if(temp==A[a]*3)

a++;

if(temp==A[b]*5)

b++;

if(temp==A[c]*7)

c++;

A[cnt++]=temp;

}

}

}

题目描述

现在我们有一个int数组,请你找出数组中每个元素的下一个比它大的元素。

给定一个int数组A及数组的大小n,请返回一个int数组,代表每个元素比他大的下一个元素,若不存在则为-1。保证数组中元素均为正整数。

测试样例:

[11,13,10,5,12,21,3],7

返回:[13,21,12,12,21,-1,-1]

代码:

import java.util.*;

public class NextElement {

    public static int[] findNext(int[] A, int n) {

int []B=new int[n];

for(int i=0;i<n;i++){

int temp=-1;

for(int j=i+1;j<n;j++){

if(A[i]<A[j]){

temp=A[j];

break;

}

}

B[i]=temp;

}

return B;

}

}

题目描述

现在有一个数组,请找出数组中每个元素的后面比它大的最小的元素,若不存在则为-1。

给定一个int数组A及数组的大小n,请返回每个元素所求的值组成的数组。保证A中元素为正整数,且n小于等于1000。

测试样例:

[11,13,10,5,12,21,3],7

[12,21,12,12,21,-1,-1]

代码:

import java.util.*;

public class NextElement {

    public static int[] findNext(int[] A, int n) {

int []B=new int[n];

for(int i=0;i<n;i++){

int temp=Integer.MAX_VALUE;

boolean ok=false;

for(int j=i+1;j<n;j++){

if(A[i]<A[j]){

ok=true;

temp=Math.min(temp, A[j]);

}

}

if(ok){

B[i]=temp;

}else{

B[i]=-1;

}

}

return B;

}

}

题目描述

请编写一个程序,按升序对栈进行排序(即最大元素位于栈顶),要求最多只能使用一个额外的栈存放临时数据,但不得将元素复制到别的数据结构中。

给定一个int[] numbers(C++中为vector&ltint>),其中第一个元素为栈顶,请返回排序后的栈。请注意这是一个栈,意味着排序过程中你只能访问到第一个元素。

测试样例:

[1,2,3,4,5]

返回:[5,4,3,2,1]

代码:

import java.util.*;

public class TwoStacks {

    public  ArrayList<Integer> twoStacksSort(int[] numbers) {

ArrayList<Integer> list=new ArrayList<>();

if(numbers.length==0){

return list;

}

Stack<Integer> stack1=new Stack<Integer>();

Stack<Integer> stack2=new Stack<Integer>();

for(int i=0;i<numbers.length;i++){

stack1.push(numbers[i]);

}

while(!stack1.isEmpty()){

int temp=stack1.pop();

while(!stack2.isEmpty()&&stack2.peek()>temp){

stack1.push(stack2.pop());

}

stack2.push(temp);

}

int len=stack2.size();

for(int i=0;i<len;i++){

list.add(stack2.pop());

}

return list;

    }

}

题目描述

实现一个函数,检查二叉树是否平衡,平衡的定义如下,对于树中的任意一个结点,其两颗子树的高度差不超过1。

给定指向树根结点的指针TreeNode* root,请返回一个bool,代表这棵树是否平衡。

代码:

import java.util.*;

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}*/

public class Balance {

   public boolean isBalance(TreeNode root) {

if (root == null)

return true;

TreeNode left=root.left;

TreeNode right=root.right;

int val=Math.abs(GetHigh(left)-GetHigh(right));//判断左数和右树的高度差

if(val>1)//如果大于1,不符合

return false;

//如果不大于1,继续判断左树的子树和右树的子树

return isBalance(left)&&isBalance(right);

}

//获取一棵树的高度

private int GetHigh(TreeNode root){

if(root==null)

return 0;

int lefthigh=GetHigh(root.left);

int righthigh=GetHigh(root.right);

return lefthigh>righthigh?(lefthigh+1):(righthigh+1);

}

}

题目描述

对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径。

给定图中的两个结点的指针UndirectedGraphNode* a,UndirectedGraphNode*b(请不要在意数据类型,图是有向图),请返回一个bool,代表两点之间是否存在一条路径(a到b或b到a)。

代码:

import java.util.*;

import java.util.ArrayList;

/*

public class UndirectedGraphNode {

    int label = 0;

    UndirectedGraphNode left = null;

    UndirectedGraphNode right = null;

    ArrayList<UndirectedGraphNode> neighbors = new ArrayList<UndirectedGraphNode>();

    public UndirectedGraphNode(int label) {

        this.label = label;

    }

}*/

public class Path {

    public boolean checkPath(UndirectedGraphNode a, UndirectedGraphNode b) {

if(a==b){

return true;

}

HashMap<UndirectedGraphNode, Boolean> map=new HashMap<UndirectedGraphNode, Boolean>();

boolean ok=Check(a,b,map);//从a开始找,b不动

map.clear();

return ok||Check(b,a,map);//从b开始找,a不动

    }

private boolean Check(UndirectedGraphNode a, UndirectedGraphNode b,HashMap<UndirectedGraphNode, Boolean> map){

if(a==b){

return true;

}

map.put(a, true);

for(int i=0;i<a.neighbors.size();i++){//从a的邻居找,看看有没有等于b的

if(!map.containsKey(a.neighbors.get(i))&&Check(a.neighbors.get(i), b, map)){

return true;

}

}

return false;

}

}

题目描述

对于一个元素各不相同且按升序排列的有序序列,请编写一个算法,创建一棵高度最小的二叉查找树。

给定一个有序序列int[] vals,请返回创建的二叉查找树的高度。

代码:

import java.util.*;

public class MinimalBST {

    public int buildMinimalBST(int[] vals) {

int length=vals.length;

if(length==0){

return 0;

}

int sum=1;

for(int i=1;i<=10000;i++){

sum<<=1;

if(sum-1>=length){

return i;

}

}

return 0;

    }

}

题目描述

对于一棵二叉树,请设计一个算法,创建含有某一深度上所有结点的链表。

给定二叉树的根结点指针TreeNode* root,以及链表上结点的深度,请返回一个链表ListNode,代表该深度上所有结点的值,请按树上从左往右的顺序链接,保证深度不超过树的高度,树上结点的值为非负整数且不超过100000。

代码:

import java.util.*;

/*

public class ListNode {

    int val;

    ListNode next = null;

    ListNode(int val) {

        this.val = val;

    }

}*/

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}*/

public class TreeLevel {

   public ListNode getTreeLevel(TreeNode root, int dep) {

ListNode listNode=new ListNode(-1);

ListNode head=listNode;

if(root==null||dep==0){

return null;

}

Queue<TreeNode> queue=new LinkedList<TreeNode>();

queue.add(root);

int ans=1;

while(!queue.isEmpty()){

int size=queue.size();

if(ans==dep){

for(int i=0;i<size;i++){

TreeNode node=queue.poll();

ListNode newhead=new ListNode(node.val);

head.next=newhead;

head=head.next;

}

break;

}else{

for(int i=0;i<size;i++){

TreeNode node=queue.poll();

TreeNode left=node.left;

TreeNode right=node.right;

if(left!=null){

queue.add(left);

}

if(right!=null){

queue.add(right);

}

}

}

ans++;

}

return listNode.next;

}

}

题目描述

请实现一个函数,检查一棵二叉树是否为二叉查找树。

给定树的根结点指针TreeNode* root,请返回一个bool,代表该树是否为二叉查找树。

代码:

import java.util.*;

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}*/

public class Checker {

 /***

* 二叉排序树(BinarySortTree),又称二叉查找树、二叉搜索树。

* 它或者是一棵空树;或者是具有下列性质的二叉树:

* 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

* 若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

* 左、右子树也分别为二叉排序树。若子树为空,查找不成功。

* @param root

* @return

*/

public boolean checkBST(TreeNode root) {

if (root == null) {

return true;

}

return Check(root,Integer.MIN_VALUE,Integer.MAX_VALUE);

}

private boolean Check(TreeNode root,int min,int max) {

if (root == null) {

return true;

}

int rootval = root.val;

TreeNode left = root.left;

TreeNode right = root.right;

if(rootval<min||rootval>max)

return false;

return Check(left, min, rootval)&&Check(right, rootval, max);

}

}

题目描述

请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。

给定树的根结点指针TreeNode* root和结点的值intp,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。

代码:

import java.util.*;

/*

public class TreeNode {

    int val = 0;

    TreeNode left = null;

    TreeNode right = null;

    public TreeNode(int val) {

        this.val = val;

    }

}*/

public class Successor {

    private static LinkedList<TreeNode> list;

public int findSucc(TreeNode root, int p) {

int result=-1;

list=new LinkedList<TreeNode>();

if(root==null){

return result;

}

DFS(root);

for(int i=0;i<list.size()-1;i++){

int val=list.get(i).val;

if(val==p){

if(list.get(i+1)!=null){

result=list.get(i+1).val;

}

break;

}

}

return result;

    }

//先中序遍历存下每个节点的信息

private void DFS(TreeNode root){

if(root==null){

return;

}

DFS(root.left);

list.add(root);

DFS(root.right);

}

}

题目描述

请设计一个算法,计算n的阶乘有多少个尾随零。

给定一个int n,请返回n的阶乘的尾零个数。保证n为正整数。

测试样例:

5

返回:1

代码:

import java.util.*;

public class Factor {

    public int getFactorSuffixZero(int n) {

int ans2 = 0, ans5 = 0, ans = 0;

for (int i = 1; i <= n; i++) {

if (i % 10 == 0) {

int temp = i;

while (temp > 0) {

if (temp % 10 == 0) {

ans++;

temp /= 10;

}else if(temp%5==0){

ans5++;

temp/=5;

}else if(temp%2==0){

ans2++;

temp/=2;

}else{

break;

}

}

} else if (i % 2 == 0) {

int temp = i;

while (temp > 0) {

if (temp % 10 == 0) {

ans++;

temp /= 10;

}else if(temp%5==0){

ans5++;

temp/=5;

}else if(temp%2==0){

ans2++;

temp/=2;

}else{

break;

}

}

} else if (i % 5 == 0) {

int temp = i;

while (temp > 0) {

if (temp % 10 == 0) {

ans++;

temp /= 10;

}else if(temp%5==0){

ans5++;

temp/=5;

}else if(temp%2==0){

ans2++;

temp/=2;

}else{

break;

}

}

}

}

return ans + Math.min(ans2, ans5);

}

}

题目描述

有一棵无穷大的满二叉树,其结点按根结点一层一层地从左往右依次编号,根结点编号为1。现在有两个结点a,b。请设计一个算法,求出a和b点的最近公共祖先的编号。

给定两个int a,b。为给定结点的编号。请返回a和b的最近公共祖先的编号。注意这里结点本身也可认为是其祖先。

测试样例:

2,3

返回:1

代码:

import java.util.*;

public class LCA {

    private static final int Max=(int) (1e6+10);

private static int dp1[];

private static int dp2[];

public static int getLCA(int a, int b) {

dp1=new int[Max];

dp2=new int[Max];

int cnt1=0,cnt2=0;

while(a>0){//储存父节点的信息

dp1[cnt1++]=a;

a>>=1;

}

while(b>0){//储存父节点的信息

dp2[cnt2++]=b;

b>>=1;

}

for(int i=0;i<cnt1;i++){

for(int j=0;j<cnt2;j++){

if(dp1[i]==dp2[j]){

return dp1[i];

}

}

}

return 1;

    }

}

题目描述

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

代码:

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 {

  private ArrayList<Integer> arrayList=new ArrayList<Integer>();

private  ArrayList<ArrayList<Integer>> list=new ArrayList<ArrayList<Integer>>();

public  ArrayList<ArrayList<Integer>> FindPath(TreeNode root, int target) {

if(root==null){

return list;

}

arrayList.add(root.val);

target-=root.val;

if(target==0&&root.left==null&&root.right==null){

list.add(new ArrayList<Integer>(arrayList));

}

FindPath(root.left,target);

FindPath(root.right,target);

if(arrayList!=null){

int size=arrayList.size();

if(size>1){

arrayList.remove(size-1);

}

}

return list;

}

}

题目描述

有两个32位整数n和m,请编写算法将m的二进制数位插入到n的二进制的第j到第i位,其中二进制的位数从低位数到高位且以0开始。

给定两个数int n和int m,同时给定int j和int i,意义如题所述,请返回操作后的数,保证n的第j到第i位均为零,且m的二进制位数小于等于i-j+1。

测试样例:

1024,19,2,6

返回:1100

代码:

import java.util.*;

public class BinInsert {

    public static int binInsert(int n, int m, int j, int i) {

int sum=n;

int cnt=j;

while(m>0){

if((m&1)==1){

sum+=POW(2, cnt);

}

cnt++;

m>>=1;

}

return sum;

}

private static  int POW(int a,int b){

int sum=1;

while(b>0){

if((b&1)==1){

sum*=a;

}

b>>=1;

a*=a;

}

return sum;

}

}

题目描述

有一个介于0和1之间的实数,类型为double,返回它的二进制表示。如果该数字无法精确地用32位以内的二进制表示,返回“Error”。

给定一个double num,表示0到1的实数,请返回一个string,代表该数的二进制表示或者“Error”。

测试样例:

0.625

返回:0.101

代码:

import java.util.*;

public class BinDecimal {

    public String printBin(double num) {

if(num>1||num<0){

return "Error";

}

StringBuilder builder=new StringBuilder();

builder.append("0.");

while(num>0){

if(builder.length()>32){

return "Error";

}

double r=num*2.0;

if(r>=1.0){

builder.append(1);

num=r-1.0;

}else{

builder.append(0);

num=r;

}

}

return builder.toString();

    }

}

题目描述

有一个正整数,请找出其二进制表示中1的个数相同、且大小最接近的那两个数。(一个略大,一个略小)

给定正整数int x,请返回一个vector,代表所求的两个数(小的在前)。保证答案存在。

测试样例:

2

返回:[1,4]

代码:

import java.util.*;

public class CloseNumber {

  public  int[] getCloseNumber(int x) {

int small = 0,big=0;

int ans=Get1Count(x);

for(int i=x-1;i>=1;i--){

if(Get1Count(i)==ans){

small=i;

break;

}

}

for(int j=x+1;;j++){

if(Get1Count(j)==ans){

big=j;

break;

}

}

return new int[]{small,big};

    }

private  int Get1Count(int n){

int ans=0;

while(n>0){

if((n&1)==1)

ans++;

n>>=1;

}

return ans;

}

}

题目描述

编写一个函数,确定需要改变几个位,才能将整数A转变成整数B。

给定两个整数int A,int B。请返回需要改变的数位个数。

测试样例:

10,5

返回:4

代码:

import java.util.*;

public class Transform {

    public int calcCost(int A, int B) {

return Get1Count(A^B);//求A和B中不相同的的个数,全部转换成1,最后算A^B中有多少个1就是了

    }

private int Get1Count(int ans){

int sum=0;

while(ans>0){

if((ans&1)==1)

sum++;

ans>>=1;

}

return sum;

}

}

题目描述

请编写程序交换一个数的二进制的奇数位和偶数位。(使用越少的指令越好)

给定一个int x,请返回交换后的数int。

测试样例:

10

返回:5

代码:

import java.util.*;

public class Exchange {

    public int exchangeOddEven(int x) {

String ans=Integer.toBinaryString(x);

if((ans.length()&1)==1){

ans="0"+ans;

}

char []array=ans.toCharArray();

for(int i=0;i<array.length;i+=2){

char temp=array[i];

array[i]=array[i+1];

array[i+1]=temp;

}

return Integer.valueOf(new String(array),2);

    }

}

题目描述

有一个排过序的字符串数组,但是其中有插入了一些空字符串,请设计一个算法,找出给定字符串的位置。算法的查找部分的复杂度应该为log级别。

给定一个string数组str,同时给定数组大小n和需要查找的string x,请返回该串的位置(位置从零开始)。

测试样例:

["a","b","","c","","d"],6,"c"

返回:3

代码:

import java.util.*;

public class Finder {

    public  int findString(String[] str, int n, String x) {

ArrayList<Node> list=new ArrayList<Node>();

for(int i=0;i<n;i++){

Node node=new Node(str[i],i);

list.add(node);

}

Collections.sort(list,new Comparator<Node>() {

@Override

public int compare(Node o1, Node o2) {

return o1.ans.compareTo(o2.ans);

}

});

int low=0;

int high=list.size()-1;

while(low<=high){

int mid=(low+high)>>1;

     String result=list.get(mid).ans;

    if(result.equals(x)){

    return list.get(mid).index;

    }else if(result.compareTo(x)>0){

    high=mid-1;

    }else{

    low=mid+1;

    }

}

return -1;

    }

class Node{

String ans;

int index;

public Node(){

}

public Node(String ans,int index){

this.ans=ans;

this.index=index;

}

}

}

题目描述

有一个NxM的整数矩阵,矩阵的行和列都是从小到大有序的。请设计一个高效的查找算法,查找矩阵中元素x的位置。

给定一个int有序矩阵mat,同时给定矩阵的大小n和m以及需要查找的元素x,请返回一个二元数组,代表该元素的行号和列号(均从零开始)。保证元素互异。

测试样例:

[[1,2,3],[4,5,6]],2,3,6

返回:[1,2]

代码:

import java.util.*;

public class Finder {

    public  int[] findElement(int[][] mat, int n, int m, int x) {

int []rws=new int[2];

int row=0,col=mat[0].length-1;

while(row<mat.length&&col>=0){

if(mat[row][col]==x){

rws[0]=row;

rws[1]=col;

break;

}else if(mat[row][col]<x){

row++;

}else{

col--;

}

}

return rws;

    }

}

--------------------- 

作者:南宫嘉俊 

来源:CSDN 

原文:https://blog.csdn.net/zyx520ytt/article/details/72466255 

版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/u011428598/article/details/83151315