# 面试题一:找出数组中重复的数字
题目描述:
在一个长度为 n 的数组里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 7 的数组 {2,3,1,0,2,5,3],那么对应的输出是重复的数字 2 或者 3。
解题思路:
通过参数 duplication 传给函数的调用者,而函数的返回值表示数组中是否有重复的数字。当输入的数组中存在重复的数字时,返回 true; 否则返回 false。
代码中尽管有一个两重循环,但每个数字最多只要交换两次就能找到属于它自己的位置,因此总的时间复杂度是 O (n)。另外,所有的操作步骤都是在输入数组上进行的,不需要额外分配内存,因此空间复杂度为 O (1)。
C++ 实现
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| #include<iostream> using namespace std; bool duplicate(int numbers[],int length,int* duplication);
int main() { cout<<"面试题一"<<endl;
int n[] = {2,2,3,4,5,2,3}; int length = sizeof(n)/sizeof(n[0]); int *duplication = new int[length]; bool success = duplicate(n,7,duplication);
if (success){ cout<<"找到重复元素:"<< *duplication<<endl; } else { cout<<"没有重复的元素"<<endl; }
delete[] duplication;
return 0; }
bool duplicate(int numbers[],int length,int* duplication) { if (numbers == nullptr||length<=0) { return false; }
for (int i = 0; i < length; ++i) { if (numbers[i] < 0 || numbers[i] > length - 1) { return false; } }
for (int i = 0; i < length; i++) { while (numbers[i] != i) { if (numbers[i] == numbers[numbers[i]]) { *duplication = numbers[i]; return true ; }
int temp = numbers[i]; numbers[i] = numbers[temp]; numbers[temp] = temp; } } return false; }
|
java 实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static int findDuplicate(int[] nums){ for (int i = 0; i < nums.length; i++) { while (nums[i] != i) { if (nums[nums[i]] == nums[i]) { return nums[i]; } swap(nums,i,nums[i]); } } return -1; }
private static void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; }
|
# 面试题二:二维数组中的查找
题目描述:
在一个二维数组中,每一行都按照从左到右递增的顺序排序。每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的 - 个二维数组和一个整数,判断数组中是否含有该整数。
解题思路:
可以使用从右上角或左下角开始搜索的方式,每次比较当前位置的值和目标值的大小,并根据大小调整搜索的方向。
这里使用从右上角开始搜索的方式,每次比较当前位置的值和目标值的大小,并根据大小调整搜索的方向。时间复杂度为 O (m+n),m 和 n 分别是二维数组的行数和列数。
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
| package Temp;
public class TestAlgorithm02 {
public static void main(String[] args) { int[][] nums = {{1,2,3}, {4,5,6}, {7,8,9}}; int target = 6; TestAlgorithm02 testAlgorithm02 = new TestAlgorithm02(); boolean search = testAlgorithm02.search(nums, 6); System.out.println(search); }
public boolean search(int[][] matrix, int target) { if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return false; } int row = 0; int col = matrix[0].length - 1; System.out.println(matrix[0].length); while (row < matrix.length && col >= 0) { if (matrix[row][col] == target) { return true; } else if (matrix[row][col] < target) { row++; } else { col--; } } return false; } }
|
# 面试题三:替换空格
题目描述:
请实现一个函数,把字符串中的每个空格替换成 "%20"。例如,输入 “Wearehappy”,则输出 “We%20are%20happy”。
解法:使用时间复杂度为 O (n) 的解法,才够搞定 Offer,换个方向想想,从后往前挪,
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
| void ReplaceBlank(char string[] ,int length) { if(string == nullptr||length<=0) return 0; int orignalLength = 0; int numberOfBlank = 0; int i = 0; while(string[i]!='\0') { ++originalLength; if(string[i] == '') ++numberOfBlank; ++ i ; } /*newLength 为把空格替换为”%20“之后的长度*/ int newLength = originLength + numberOfBlank*2; if(newLength > length) return; int indexOfOriginal = originalLength; int indexOfNew = newLength; while(indexOfOringinal >= 0 && indexOfNew >indexOfOriginal) { if(string[indexOfOringinal]=='') { string[indexOfNew -- ]='0'; string[indexOfNew -- ]='2'; string[indexOfNew -- ]='%';
} else { string[indexOfNew--] = string[indexOfOringinal]; } --indexOfOriginal; } }
|
# 从头到尾打印链表
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| package Algorithm;
import java.util.ArrayList; import java.util.LinkedList; import java.util.Stack;
public class TestAlgorithm04 {
public static void main(String[] args) { LinkedList<String> list = new LinkedList<>(); list.add("abb"); list.add("bcc"); list.add("cdd");
for (String i: list) { System.out.println(i); } System.out.println("++++++++++++++++++++"); solution solution = new solution(); ArrayList<String> list1 = solution.printListFromTailToHead(list); for (String d: list1) { System.out.println(d); }
}
public static class solution { public ArrayList<String> printListFromTailToHead(LinkedList linkedList){ Stack<String> stack = new Stack<>(); for (int i = 0; i < linkedList.size(); i++) { stack.push(linkedList.get(i).toString()); } ArrayList<String> list = new ArrayList<String>(); while (!stack.isEmpty()) { list.add(stack.pop()); }
return list; } } }
|
# 重建二叉树
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| package Algorithm;
import java.util.HashMap;
class TreeNode { int val; TreeNode left; TreeNode right; TreeNode (int x){ val = x; } }
public class TestAlgorithm05 {
private HashMap<Integer, Integer> map;
public TreeNode buildTree(int[] preorder,int[] inorder){ map = new HashMap<Integer,Integer>(); for (int i = 0; i < inorder.length; i++) { map.put(inorder[i],i); }
return buildTree(preorder,inorder,0,preorder.length-1,0,inorder.length-1); }
private TreeNode buildTree(int[] preorder,int[] inorder,int preLeft,int preRight,int inLeft,int inRight){ if (preLeft > preRight || inLeft > inRight) { return null; }
TreeNode root = new TreeNode(preorder[preLeft]); int rootIndex = map.get(preorder[preLeft]); int leftSize = rootIndex - inLeft;
root.left = buildTree(preorder, inorder, preLeft+1, preLeft+leftSize, inLeft, rootIndex-1); root.right = buildTree(preorder, inorder, preLeft+leftSize+1, preRight, rootIndex+1, inRight);
return root; }
public static void main(String[] args) { int[] preorder = {3,9,20,15,7}; int[] inorder = {9,3,15,20,7};
TestAlgorithm05 s = new TestAlgorithm05(); TreeNode root = s.buildTree(preorder, inorder);
printTree(root); }
public static void printTree(TreeNode root) { if(root == null) { return; }
System.out.print(root.val + " "); printTree(root.left); printTree(root.right); }
}
|
# 用两个栈实现队列
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
| package Algorithm;
import java.util.Stack;
public class TestAlgorithm06 {
Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>();
public void appendTail(int value){ stack1.push(value); }
public int deleteHead() { if (stack2.empty()) { while (!stack1.empty()) { stack2.push(stack1.pop()); } } if (stack2.empty()){ throw new RuntimeException("Queue is empty."); } return stack2.pop(); } public static void main(String[] args) { TestAlgorithm06 queue = new TestAlgorithm06(); queue.appendTail(1); System.out.println(queue.deleteHead()); queue.appendTail(2); System.out.println(queue.deleteHead());
queue.appendTail(3); queue.appendTail(4); queue.appendTail(5); System.out.println(queue.deleteHead()); System.out.println(queue.deleteHead()); }
}
|
# 斐波那契
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
| package Algorithm;
public class TestAlgorithm07 {
public static void main(String[] args) { int a = 3; int fibonacci = fibonacci(a); System.out.println("第"+a+"位斐波那契数的值为:"+fibonacci); } public static int fibonacci(int n){ if (n <= 0) { return 0; } else if (n == 1) return 1; else { int a = 0,b = 1, c = 0; for (int i = 2; i <= n; i++) { c = a + b; a = b; b = c; } return c; } } }
|
# 青蛙跳台阶
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
| package Algorithm;
public class TestAlgorithm08 {
public static void main(String[] args) { int n = 20; int jumpFloor = jumpFloor(n); System.out.println("方法个数为:"+jumpFloor); }
public static int jumpFloor(int n) { if (n <= 0) return 0; else if (n == 1) return 1; else if (n == 2) return 2; else { int pre = 2, prepre = 1, cur = 0; for (int i = 3; i <= n; i++) { cur = pre + prepre; prepre = pre; pre = cur; } return cur; } } }
|
# 旋转数组最小值
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
| package Algorithm;
public class TestAlgorithm09 {
public static void main(String[] args) { int[] nums = {3,4,5,1,2}; int min = findMin(nums); System.out.println("最小值为:"+min); }
public static int findMin(int[] nums){ int left = 0,right = nums.length - 1;
while (left < right) { int mid = (left+right)/2; if (nums[mid]>nums[right]){ left = mid + 1; }else if (nums[mid] == nums[right]){ right -- ; }else { right = mid; } }
return nums[left]; }
}
|
# 矩阵中的路径
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 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| package Algorithm;
public class TestAlgorithm10 {
public static void main(String[] args) { char[][] nums = {{'a','b','t','g'}, {'c','f','c','s'}, {'j','d','e','h'}}; boolean result = hasPath(nums, "bfce"); System.out.println("存在一条路径:"+result); }
public static boolean hasPath(char[][] matrix,String str){ while (matrix == null || matrix.length == 0 || str == null || str.length() == 0) { return false; } boolean[][] visited = new boolean[matrix.length][matrix[0].length]; for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { if (matrix[i][j] == str.charAt(0)){ if (dfs(matrix,str,visited,i,j,0)){ return true; } } } } return false; }
private static boolean dfs(char[][] matrix,String str,boolean[][] visited,int row,int col,int index){ if (index == str.length()) { return true; } if (row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length || visited[row][col]) { return false; } if (matrix[row][col] != str.charAt(index)) { return false; } visited[row][col] = true; boolean result = dfs(matrix, str, visited, row - 1, col, index + 1) || dfs(matrix, str, visited, row + 1, col, index + 1) || dfs(matrix, str, visited, row, col - 1, index + 1) || dfs(matrix, str, visited, row, col + 1, index + 1); visited[row][col] = false;
return result; } }
|