剑指offer Day5

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;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值