面試題目彙總(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<int>),其中第一個元素為棧頂,請返回排序後的棧。請注意這是一個棧,意味著排序過程中你只能訪問到第一個元素。
測試樣例:
[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
版權宣告:本文為博主原創文章,轉載請附上博文連結!