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