剑指offer题目--优化时间和空间效率

29 数组中出现次数超过一半的数字

方法1:

import java.util.Arrays;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        Arrays.sort(array);
        int count=0;
         
        for(int i=0;i<array.length;i++){
            if(array[i]==array[array.length/2]){
                count++;
            }
        }
        if(count>array.length/2){
            return array[array.length/2];
        }else{
            return 0;
        }
    }
}

方法2:HashMap

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
         
        for(int i=0;i<array.length;i++){
             
            if(!map.containsKey(array[i])){
               map.put(array[i],1);
            }else{
                int count = map.get(array[i]);
                map.put(array[i],++count);
            }
        }
        Iterator iter = map.entrySet().iterator();
        while(iter.hasNext()){
            Map.Entry entry = (Map.Entry)iter.next();
            Integer key =(Integer)entry.getKey();
            Integer val = (Integer)entry.getValue();
            if(val>array.length/2){
                return key;
            }
        }
        return 0;
    }
}

方法3:快排思想--未通过

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
       if(array.length<=0)
                return 0;

        int start = 0;
        int length = array.length;
        int end  = length-1;
        int middle = length>>1;

        int index = Partition(array,start,end);

        while(index!=middle){

            if(index>middle){
                index = Partition(array,start,index-1);
            }
            else{
                index = Partition(array,index+1,end);
            }
        }
        int result = array[middle];

        int times = 0;
        for(int i=0;i<length;++i){
            if(array[i] == result)
                times++;
        }
        if(times*2<length){
            System.out.println(times);
            return 0;
        }else{
            return result;
        }
    }
    
    public int Partition(int[] array,int start,int end){
        int flag = (array[start]+array[end])/2;

        while(start<end){
            while(array[end]>flag){
                end--;
            }
            swap(array,start,end);
            while(array[start]<=flag){
                start++;
            }
            swap(array,start,end);
        }
        return start;
    }
    public void swap(int[] array,int num1,int num2){
        int temp =array[num1];
        array[num1] =array[num2];
        array[num2] =temp;
    }
}

 

30 最小的K个数

解法一:冒泡排序

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> al = new ArrayList<Integer>();
        if (k > input.length) {
            return al;
        }
        for (int i = 0; i < k; i++) {
            for (int j = 0; j < input.length - i - 1; j++) {
                if (input[j] < input[j + 1]) {
                    int temp = input[j];
                    input[j] = input[j + 1];
                    input[j + 1] = temp;
                }
            }
            al.add(input[input.length - i - 1]);
        }
        return al;
    }
}

解法2:利用快速排序中的获取分割(中轴)点位置函数getPartitiion--用例未通过

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) {
        ArrayList<Integer> result = new ArrayList<Integer>();       
        if(input==null || k>input.length || k<=0) return result;
         
        int start = 0;
        int end = input.length-1;
        int index = getPartition(input,start,end);
         
        while(index != (k-1))
        {
            if(index > (k-1))
            {
                end = index - 1;
                index = getPartition(input,start,end);
            }
            else
            {
                start = index + 1;
                index = getPartition(input,start,end);
            }
        }
         
        for(int i=0;i<k;++i)
        {
            result.add(input[i]);
        }
         
        return result;
    }
    public void swap(int fir,int sec)
    {
        int temp = fir;
        fir = sec;
        sec = temp;
    }
     
    public int getPartition(int [] input,int start,int end)
    {
        if(input==null || start>end) return -1;
        int temp = input[end];
        int j = start - 1;
        for(int i=start;i<end;++i)
        {
            if(input[i]<=temp)
            {
                ++j;
                if(i!=j) swap(input[i],input[j]);                   
            }
        }
        swap(input[j+1],input[end]);
        return (j+1);
    }
}

 

31 连续子数组的最大和

解法1:分析数组规律

public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        int len = array.length;
        if(array==null || len<0){
            return 0;
        }
        int nCurSum = 0;
        int nGreatestSum = 0x80000000;
        for(int i=0; i<len;i++){
            if(nCurSum <= 0){
                nCurSum = array[i];
            }else{
                nCurSum += array[i];
            }
            if(nCurSum > nGreatestSum){
                nGreatestSum = nCurSum;
            }
        }
        return nGreatestSum;
    }
}

解法2:动态规划思想,代码一致

32 从1到n整数中1出现的次数 

 

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int number = 0;
        for(int i=0;i<=n;i++){
            number += numberOf1(i);
        }
        return number;
    }
    public int numberOf1(int n){
        int number = 0;
        while(n>0){
            if(n%10 == 1){
                number ++;
            }
            n = n/10;
        }
        return number;
    }
}

 

33 把数组排成最小的数

 

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        int n;
        String s="";
        ArrayList<Integer> list= new ArrayList<Integer>();
        n=numbers.length;
        for(int i=0;i<n;i++){
            list.add(numbers[i]);
        }

        Collections.sort(list, new Comparator<Integer>(){
  
            public int compare(Integer str1,Integer str2){
                String s1=str1+""+str2;
                String s2=str2+""+str1;
                return s1.compareTo(s2);
            }
        });

        for(int j:list){
            s+=j;
        }
        return s;
    }
}

 

import java.util.ArrayList;

public class Solution {
    public String PrintMinNumber(int [] numbers) {
        String str = "";
        for (int i=0; i<numbers.length; i++){
            for (int j=i+1; j<numbers.length; j++){
                int a = Integer.valueOf(numbers[i]+""+numbers[j]);
                int b = Integer.valueOf(numbers[j]+""+numbers[i]);
                if (a > b){
                    int t = numbers[i];
                    numbers[i] = numbers[j];
                    numbers[j] = t;
                }
                 
            }
        }
        for (int i = 0; i < numbers.length; i++) {
            str += String.valueOf(numbers[i]);
        }
        return str;
    }
}

 

34 丑数

解法一:暴力破解 超时

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index <= 0){
            return 0;
        }
        int number = 0;
        int uglyFound = 0;
        while(uglyFound < index){
            ++number;
            if(IsUgly(number)){
                ++uglyFound;
            }
        }
        return number;        
    }
    boolean IsUgly(int number){
        while(number % 2 == 0){
            number /= 2;
        }
        while(number % 3 == 0){
            number /= 3;
        }
        while(number % 5 == 0){
            number /= 5;
        }
        return (number==1)?true:false;
    }
}

方法二:创建数组保存已找到的丑数,用空间换时间

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index <=0){
            return 0;
        }

        int[] uglyNums = new int[index];
        uglyNums[0]=1;
        
        int nextUglyIndex = 1;
        int mul2 = 0;
        int mul3 = 0;
        int mul5 = 0;
        
        while(nextUglyIndex < index){
            int min = Min(uglyNums[mul2]*2, uglyNums[mul3]*3, uglyNums[mul5]*5);
            uglyNums[nextUglyIndex] = min;
            
            while(uglyNums[mul2]*2 <= uglyNums[nextUglyIndex]){
                ++mul2;
            }
            while(uglyNums[mul3]*3 <= uglyNums[nextUglyIndex]){
                ++mul3;
            }
            while(uglyNums[mul5]*5 <= uglyNums[nextUglyIndex]){
                ++mul5;
            }
            ++nextUglyIndex;
        }
        int ugly = uglyNums[nextUglyIndex - 1];
        return ugly;            
    }
    
    int Min(int num1, int num2, int num3){
        int min = (num1 <= num2)?num1:num2;
        min = (min <= num3)?min:num3;
        return min;
    }
}

 

35 第一个只出现一次的字符

方法1:哈希表 ASCII码

public class Solution {
    public int FirstNotRepeatingChar(String str) {
    int[] words = new int[58];
    for(int i = 0;i<str.length();i++){
        words[((int)str.charAt(i))-65] += 1;
    }
    for(int i=0;i<str.length();i++){
        if(words[((int)str.charAt(i))-65]==1)
            return i;
    }
    return -1;
    }
}

方法2:字符串函数  第一次和最后一次出现的位置相同

public class Solution {
    public int FirstNotRepeatingChar(String str) {
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (str.indexOf(ch) == str.lastIndexOf(ch))
                return i;
        }
        return -1;
    }
}

 

***相似题目*** 统计多个字符是不是在字符串出现过或者次数

删除第一个字符串中在第二个字符串中出现的字符

删除字符串中所有重复出现的字符

变位词

36 数组中的逆序对

方法1:归并排序 按书上代码没有通过用例

public class Solution {
    public int InversePairs(int [] array) {
        if(array == null || array.length <0){
            return 0;
        }
        int len = array.length;
        int[] copy = new int[len];
        for(int i=0;i<len;++i){
            copy[i] = array[i];
        }
        int count  = InversePairsCore(array,copy,0,len-1);
        
        return count;
    }
    
    int InversePairsCore(int[] array, int[] copy, int start, int end){
        if(start == end){
            copy[start] = array[start];
            return 0;
        }
        int len = (end - start)/2;
        
        int left = InversePairsCore(copy, array, start, start + len);
        int right = InversePairsCore(copy, array, start + len+1,end);
        
        int i =start +len;
        int j=end;
        int indexCopy = end;
        int count = 0;
        while(i>= start && j >= start + len+ 1){
            if(array[i] > array[j]){
                copy[indexCopy--] = array[i--];
                count += j-start-len;
            }else{
                copy[indexCopy--] = array[j--];
            }
        }
        for(;i>=start;--i){
            copy[indexCopy--] = array[i];
        }
        for(;j>= start + len +1;--j){
            copy[indexCopy] = array[j];
        }
        return left+right+count;
    }
}

 

37 两个链表的第一个公共结点

 

public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        int len1 = GetListLen(pHead1);
        int len2 = GetListLen(pHead2);
        int lendif = len1-len2;
        
        ListNode headLong = pHead1;
        ListNode headShort = pHead2;
        if(len2>len1){
            headLong = pHead1;
            headShort = pHead2;
            lendif = len2-len1;
        }
        
        for(int i=0;i<lendif;++i){
            headLong = headLong.next;
        }
        while(headLong != null && headShort != null && headLong != headShort){
            headLong = headLong.next;
            headShort = headShort.next;
        }
        ListNode firstCommNode = headLong;
        return firstCommNode;
    }
    int GetListLen(ListNode pHead){
        int len = 0;
        ListNode pNode = pHead;
        while(pNode != null){
            ++ len;
            pNode = pNode.next;
        }
        return len;
    }
}

 

posted @ 2020-02-19 22:14  小仙女学编程  阅读(156)  评论(0编辑  收藏  举报