• 剑指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;
        }
    }
  • 相关阅读:
    Java工作中常用到的工具
    得到区块链直播记录
    如何高效的解决问题
    pgsql数据库应用两点注意
    flask如何使模板返回大文件,又不消耗大量内存
    python内存诊断
    pycharm整体缩进的快捷键
    gdb生成的core文件位置
    gdb源码安装,指定使用的python版本
    gdb源码安装过程中的问题:no termcap library found
  • 原文地址:https://www.cnblogs.com/coding-fairyland/p/12333510.html
Copyright © 2020-2023  润新知