[程序员代码面试指南]判断字符数组中是否所有字符只出现一次(堆排序)
题意
如题,并要求额外空间复杂度为O(1)。
题解
- 若不要求额外空间复杂度。普通做法时间复杂度O(n).
- 此题思路是先排序,然后判断相邻两个是否有重复元素。时间复杂度O(n),空间复杂度O(1).
堆排序再理解
堆排序步骤
1、堆的初始化,从最后一个非叶节点为根调整,向前一个个节点为根调整。
2、从最后一个元素开始分别和堆顶元素swap,始终以树的第一个位置的节点为根调整。
代码
package Character;
import java.util.Scanner;
public class OccurOnece {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String str=in.next();
boolean ans=isUnique(str.toCharArray());
if(ans) {
System.out.print("Unique.");
}
else {
System.out.print("Not unique.");
}
}
public static boolean isUnique(char[] str) {
if(str==null) {
return true;
}
heapSort(str);
for(int i=0;i<str.length-1;++i) {
if(str[i]==str[i+1]) {
return false;
}
}
return true;
}
public static void heapSort(char[] str) {//堆排序
buildHeap(str);//建堆 heapify一波
for(int i=str.length-1;i>=0;--i) {//排序 swap、heapify一波
swap(str,0,i);
heapify(str,0,i-1);
}
}
public static void buildHeap(char[] str) {
for(int i=str.length/2-1;i>=0;--i) {
heapify(str,i,str.length-1);
}
}
public static void heapify(char[] str,int idx,int heapSize) {
int lIdx=idx*2+1;
int rIdx=idx*2+2;
int maxIdx=idx;
while(lIdx<=heapSize) {
if(str[lIdx]>str[idx]) {
maxIdx=lIdx;
}
if(rIdx<=heapSize&&str[rIdx]>str[idx]) {
maxIdx=rIdx;
}
if(maxIdx!=idx) {
swap(str,idx,maxIdx);
idx=maxIdx;
lIdx=idx*2+1;
rIdx=idx*2+2;
}
else break;//到当前节点是以它为根节点的数的最大值停止
}
}
public static void swap(char[] str,int idx1,int idx2) {
char tmp=str[idx1];
str[idx1]=str[idx2];
str[idx2]=tmp;
}
}
posted on 2019-06-18 23:08 coding_gaga 阅读(384) 评论(0) 编辑 收藏 举报