Problem 1:
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:
输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
1. Recursion(166ms)
func(a,b,c)=a(func(b,c))+ exchange a and b(func(a,c))+ exchange a and c(func(b,a))
func(b,c) = b+func(c)+ exchange b and c(func(b))
func(c)=1
import java.util.ArrayList;
import java.util.Collections;
public class Solution {
public ArrayList<String> Permutation(String str) {
StringBuilder string = new StringBuilder(str);
ArrayList<String> result = findPermutation(string);
return result;
}
public ArrayList<String> findPermutation(StringBuilder str){
ArrayList<String> result = new ArrayList<String>();
if(str.length() == 1)
result.add(str.toString());
else{
for(int i = 0; i < str.length(); i++){
if(i == 0 || str.charAt(i) != str.charAt(0)){
char temp = str.charAt(i);
str.setCharAt(i, str.charAt(0));
str.setCharAt(0, temp);
ArrayList<String> newResult = findPermutation(new StringBuilder(str.substring(1)));
for(int j = 0; j < newResult.size(); j++){
result.add(str.substring(0,1) + newResult.get(j));
}
temp = str.charAt(i); //recover
str.setCharAt(i, str.charAt(0));
str.setCharAt(0, temp);
}
}
}
Collections.sort(result); // sort by lexicographical order
return result;
}
}
2.Backtracking
import java.util.*;
public class Solution {
private ArrayList<String> result = new ArrayList<String>();
private TreeSet<String> paths = new TreeSet<>();
private StringBuilder path = new StringBuilder();
private boolean [] visit;
public ArrayList<String> Permutation(String str) {
if(str == null || str.equals(""))
return result;
char[] strs = str.toCharArray();
Arrays.sort(strs);
visit = new boolean[strs.length];
findPermutation(strs, 0);
result.addAll(paths);
return result;
}
private void findPermutation(char[] str, int len){
if(len == str.length){
paths.add(path.toString());
return;
}
for(int i = 0; i < str.length; i++){
if(!visit[i]){
visit[i] = true;
path.append(str[i]);
findPermutation(str, len + 1);
// reset
visit[i] = false;
path.deleteCharAt(path.length() - 1);
}
}
}
}
Problem 2:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为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 == null){
return 0;
}
int pre = array[0];
int count = 0;
for(int i = 0; i < array.length; i++){
if(array[i] == pre){
count++;
}
else{
count--;
if(count == 0){
pre = array[i];
count = 1;
}
}
}
int n = 0;
for(int i = 0; i < array.length; i++){
if(array[i] == pre){
n++;
}
}
return n > array.length / 2 ? pre : 0;
}
}
2. Stream class
import java.util.Arrays;
import java.util.stream.IntStream;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
Arrays.sort(array);
int i = array[array.length / 2];
return IntStream.of(array).filter(k -> k == i).count() > array.length / 2 ? i : 0;
}
}
Problem 3:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
1. Use heap data structure
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<>();
if (input == null || input.length == 0 || k == 0 || k > input.length) {
return list;
}
int [] arr = new int[k + 1];
for (int i = 1; i < arr.length; i++) {
arr[i] = input[i - 1];
}
buildMaxHeap(arr, k + 1);
for (int i = k; i < input.length; i++) {
if (input[i] < arr[1]) {
arr[1] = input[i];
heapAdjust(arr, 1, arr.length - 1);
}
}
for (int i = 1; i < arr.length; i++) {
list.add(arr[i]);
}
return list;
}
private void buildMaxHeap(int [] arr, int length) {
for (int i = (length - 1) / 2; i >= 1; i--) {
heapAdjust(arr, 1, length - 1);
}
}
private void heapAdjust(int [] arr, int low, int high) {
arr[0] = arr[low];
for (int j = low * 2; j <= high; j *= 2) {
if (j < high && arr[j + 1] > arr[j])
j++;
if (arr[0] >= arr[j])
break;
arr[low] = arr[j];
low = j;
}
arr[low] = arr[0];
}
}
2. Insertion Sort
import java.util.ArrayList;
public class Solution {
public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
ArrayList<Integer> list = new ArrayList<>();
if (input == null || input.length == 0 || k == 0 || k > input.length) {
return list;
}
for (int i = 1; i < k; i++) {
int j = i - 1;
int temp = input[i];
while (j >= 0 && input[j] > temp) {
input[j + 1] = input[j];
j--;
}
input[j + 1] = temp;
}
for (int i = k; i < input.length; i++) {
if (input[i] < input[k - 1]) {
int j = k - 1;
int temp = input[i];
while (j >= 0 && input[j] > temp) {
input[j + 1] = input[j];
j--;
}
input[j + 1] = temp;
}
}
for (int i = 0; i < k; i++) {
list.add(input[i]);
}
return list;
}
}
3. Priority Queue
import java.util.PriorityQueue;
/*
Time complexity: O(n * logk)
Space complexity: O(k)
*/
class Solution {
public int[] getLeastNumbers2(int[] arr, int k) {
if (arr == null || arr.length == 0 || k == 0) {
return new int[0];
}
PriorityQueue<Integer> bigHeap = new PriorityQueue<>(
(o1, o2) -> o2 - o1
);
for (int num : arr) {
bigHeap.add(num);
// keep the size of big root heap is k.
if (bigHeap.size() > k) {
bigHeap.poll();
}
}
return bigHeap.stream().mapToInt(Integer::intValue).toArray();
}
}
Problem 4:
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
int maxValue = array[0];
int [] dp = new int[array.length];
dp[0] = array[0];
for (int i = 1; i < array.length; i++) {
dp[i] = Math.max(array[i], dp[i - 1] + array[i]);
maxValue = Math.max(dp[i], maxValue);
}
return maxValue;
}
}
public class Solution {
public int FindGreatestSumOfSubArray(int[] array) {
int maxValue = array[0];
for (int i = 1; i < array.length; i++) {
array[i] += array[i - 1] > 0 ? array[i - 1] : 0;
maxValue = Math.max(array[i], maxValue);
}
return maxValue;
}
}