Java常用算法

Java常用算法

2017-06-21

目录

1 去重
  1.1 去重
  1.2 去不重
2 随机分配
3 递归
4 内部排序变形
  4.1 取数组中未出现的最小整数
5 字符串
  5.1 全排序
  5.2 找最大回文
  5.3 字符串转换为数字
  5.4 和为指定值的两个数
  5.5 字符串是否对应
  5.6 出现频率最高10位数 

1 去重

1.1 去重

    //去重复,需要额外定义一个List
    public static void RemoveRepeat(List<Integer> arrs) {
        List<Integer> tmp = new ArrayList<Integer>();
        Iterator<Integer> it = arrs.iterator();
        while (it.hasNext()) {
            int a = it.next();
            if (tmp.contains(a))
                it.remove();
            else
                tmp.add(a);
        }
    }

1.2 去不重

    // 去不重复的数,用的是选择排序算法变化版
    public static void RemoveNoRepeat(List<Integer> arrs) {
        Boolean isRepeate = false;
        for (int i = 0; i < arrs.size(); i++) {
            isRepeate = false;
            for (int j = 0; j < arrs.size(); j++) {
                if (arrs.get(i) == arrs.get(j) && i != j) {
                    isRepeate = true;
                    break;
                }
            }
            if (!isRepeate) {
                arrs.remove(i);
                i--;
            }
        }
    }

    public static void RemoveNoRepeatImprove(List<Integer> arrs) {
        Boolean isRepeate = false;
        for (int i = arrs.size() - 1; i >= 0; i--) {
            isRepeate = false;
            for (int j = arrs.size() - 1; j >= 0; j--) {
                if (arrs.get(i) == arrs.get(j) && i != j) {
                    isRepeate = true;
                    break;
                }
            }
            if (!isRepeate) {
                arrs.remove(i);
            }
        }
    }

    public static void RemoveNoRepeatWithExtraMap(List<Integer> arrs) {
        Map<Integer, Integer> repeat = CountRepeat(arrs);

        for (int i = arrs.size() - 1; i >= 0; i--) {
            if (repeat.get(arrs.get(i)) == 1) {
                arrs.remove(i);
            }
        }
    }

    // 统计重复数
    public static Map<Integer, Integer> CountRepeat(List<Integer> arrs) {
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        Integer value = 0;
        for (Integer arr : arrs) {
            if (map.containsKey(arr)) {
                value = map.get(arr);
                map.put(arr, value + 1);
            } else {
                map.put(arr, 1);
            }
        }
        return map;
    }

HashMap实现

public static void RemoveNotRepeat(List<Character> arrs)
    {
        Map<Character,Integer> tmp=new HashMap();
        for(char c:arrs)
        {
            if(tmp.containsKey(c))
                tmp.put(c,tmp.get(c)+1);
            else
                tmp.put(c,1);
        }
        Iterator<Character> it=arrs.iterator();

        while (it.hasNext())
        {
            Character c=it.next();
            if(tmp.get(c)==1)
                it.remove();
        }
    }
View Code

 

2 随机分配

    public static Map<String, String> TicketDispatch(List<String> customers, List<String> tickets) {
        Map<String, String> result = new HashMap<String, String>();

        Random r = new Random();
        int iCustomer;
        int iTicket;
        for (int i = customers.size(); i > 0; i--) {
            // 取值范围[0,i)
            iCustomer = r.nextInt(i);
            iTicket = r.nextInt(tickets.size());

            result.put(customers.get(iCustomer), tickets.get(iTicket));
            customers.remove(iCustomer);
            tickets.remove(iTicket);
        }

        return result;
    }

3 递归

    //Java递归删除一个目录下文件和文件夹
    private static void deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            // 递归删除目录中的子目录下
            for (int i=0; i<children.length; i++) {
               deleteDir(new File(dir, children[i]));               
            }
        }
        dir.delete();
    }

4 内部排序变形

4.1 取数组中未出现的最小整数

    public static Integer GetNotExitMinInteger(Integer[] arr)
    {
        Integer minIndex;
        Integer tmp;
        Integer first=0;
        for(int i=0;i<arr.length;i++)
        {        
            minIndex=i;
            for(int j=i+1;j<arr.length;j++)
            {
                if(arr[minIndex]>arr[j])
                    minIndex=j;
            }
            
            if(arr[minIndex]-first>1)
                return first+1;
            else
            {
                first=arr[minIndex];
            }
            
            if(minIndex!=i)
            {
                tmp=arr[i];
                arr[i]=arr[minIndex];
                arr[minIndex]=tmp;
            }
        }
        return arr[arr.length-1]+1;
    }

上面问题其他解决方案:

也可先排序(快速排序,若范围可确定,且不到,可用桶排序),在先后比较arr[next]-arr[one]>1

 

HashMap实现

    public static Integer GetNotExitMinIntegerByHashMap(Integer[] arr) {
        Integer minKey=Integer.MAX_VALUE;
        Integer maxKey=Integer.MIN_VALUE;
        Map<Integer,Integer> map=new HashMap<Integer,Integer>();

        for(int i=0;i<arr.length;i++)
        {
            map.put(arr[i],arr[i]);
            if(minKey>arr[i])
                minKey=arr[i];
            if(maxKey<arr[i])
                maxKey=arr[i];
        }

        Integer pre=minKey;

        if(minKey>1)
            return minKey-1;

        while(pre<=maxKey) {
            if(map.get(pre+1)==null)
                return pre+1;
            else
                ++pre;
        }

        return maxKey+1;
    }
View Code

 

5 字符串

5.1 全排序

思路:

n个字符

  • 前n-1个固定,第n个,不能再互换,打印排列
  • 前n-2个固定,第n-1个和n位置互换,得到排列
  • 前n-3个固定,第n-2个分别和最后两个位置互换
  • ...
public class FullPermutation {
    public static void main(String[] args)
    {
        char[] arr=new char[]{'A','B','C','D'};
        Permutatition(arr);
    }

    public static void Permutatition(char[] arr)
    {
        recursivePermutation(arr,0,arr.length-1);
    }

    private static void recursivePermutation(char[] arr,int start,int end)
    {
        if(start==end) {
            for (int i = 0; i <= end; i++)
                System.out.print(arr[i]);
            System.out.println();
        }
        else {
            for (int i = start; i <= end; i++) {
                swap(arr, start, i);
                recursivePermutation(arr, start+1, end);
                swap(arr, start, i);
            }
        }
    }

    private static void swap(char[] arr,int left,int right)
    {
        char tmp=arr[left];
        arr[left]=arr[right];
        arr[right]=tmp;
    }
}
View Code

5.2 找最大回文

回文:正读,倒读一样

样例:abcdedcba,abcddcba

思路:中心点,看两边是否对应

public static String longestPalindrome(String str)
    {
        if(str==null||str.length()==0)
            return "";

        int max=0,current=0,length=str.length();
        String subString="";

        for(int i=0;i<length;i++)
        {
            //考虑回文字段为奇数长度
            for(int j=0;i-j>=0&&i+j<length;j++)
            {
                if(str.charAt(i-j)!=str.charAt(i+j))
                    break;
                current=j*2+1;
            }
            if(current>max)
            {
                max=current;
                subString=str.substring(i-max/2,i+max/2+1);
            }
            //考虑回文字段为偶数长度
            for(int j=0;i-j>=0&&i+j+1<length;j++)
            {
                if(str.charAt(i-j)!=str.charAt(i+j+1))
                    break;
                current=j*2+2;
            }
            if(current>max)
            {
                max=current;
                subString=str.substring(i-max/2+1,i+max/2+1);
            }
        }

        return subString;
    }
View Code

5.3 字符串转换为数字

    public static int toInt(String str)
    {
        if(str==null&&str.length()==0)
            throw new RuntimeException("字符串为空");

        //转换结果
        int result=0;
        //要转换的字符
        int current=0;
        //整数的正负
        char sign='+';
        if(str.charAt(0)=='-'||str.charAt(0)=='+')
        {
            sign=str.charAt(0);
            str=str.substring(1);
        }

        //是否需要判断
        boolean judgeOverflow=true;
        if(str.length()>10)
        {
            throw new RuntimeException("整形溢出了");
        }
        else if(str.length()<10)
        {
            judgeOverflow=false;
        }

        for(int i=0;i<str.length();i++){
            current=str.charAt(i)-'0';
            if(current>9||current<0)
                throw new RuntimeException("包含非整数型字符");
            if(judgeOverflow)
            {
                if(sign=='+'&&current>Integer.MAX_VALUE/(int)Math.pow(10,9-i)%10)
                {
                    throw new RuntimeException("整形溢出了");
                }
                if(sign=='-'&&current>Math.abs(Integer.MIN_VALUE/(int)Math.pow(10,9-i)%10))
                {
                    throw new RuntimeException("整形溢出了");
                }
            }
            result=result*10+current;
        }
        if(sign=='-')
        {
            result=-result;
        }
        return result;
    }
View Code

 

5.4 和为指定值的两个数

思路

1 先排序,后加

2 用哈希表,key为数的值,value为位置。这样,hashMap.get(sum-arr[i]),O(1)定位

public class TwoSum {
    public static void main(String[] args)
    {
        int[] arr=new int[]{7,8,5,4,1,2,3,6,9};
        findByHash(arr,10);
        int[] arr2=new int[]{1,2,3,4,5,6,7,8,9};
        find(arr2,10);
    }

    public static void find(int[] arr,int sum)
    {
        //arr 这里arr是排好序的了
        int begin=0;
        int end=arr.length-1;
        while(begin<end)
        {
            if(arr[begin]+arr[end]==sum) {
                System.out.println(String.format(("[%d,%d]"), arr[begin], arr[end]));
                begin++;
            }
            else if(arr[begin]+arr[end]>0)end--;
            else begin++;
        }

    }

    public static void findByHash(int[] arr, int sum)
    {
        Hashtable<Integer,Integer> hashMap=new Hashtable<>();
        for(int i=0;i<arr.length;i++)
        {
            hashMap.put(arr[i],i);
        }

        for(int i=0;i<arr.length;i++)
        {
            int index=hashMap.get(sum-arr[i]);
            if(index!=-1&&index>i) {
                System.out.println(String.format(("[%d,%d]"), arr[i], arr[index]));
            }
        }
    }
}
View Code

5.5 字符串是否对应

1 pattern="aabac"

2 target="dog dog pig dog cat"

3 target=="dog dog pig dog dog"

1、2模式一致,1、3模式不一致

public static boolean isPatternMatch(String pattern,String target)
    {
        Map<Character,String> mPatternTarget=new HashMap<>();
        char[] cPattern=pattern.toCharArray();
        String[] strTarget=target.split(" ");
        for(int i=0;i<cPattern.length;i++)
        {
            if(!mPatternTarget.containsKey(cPattern[i]))
                mPatternTarget.put(cPattern[i],strTarget[i]);
            else
            {
                if(!mPatternTarget.get(cPattern[i]).equals(strTarget[i]))
                    return false;
            }
        }
        return true;
    }
View Code

5.6 出现频率最高10位数

hashmap按值,按排序

public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("c", "ccccc");
        map.put("a", "aaaaa");
        map.put("b", "bbbbb");
        map.put("d", "ddddd");
        
        List<Map.Entry<String,String>> list = new ArrayList<Map.Entry<String,String>>(map.entrySet());
        Collections.sort(list,new Comparator<Map.Entry<String,String>>() {
            //升序排序
            public int compare(Entry<String, String> o1,
                    Entry<String, String> o2) {
                return o1.getValue().compareTo(o2.getValue());
            }
            
        });
        
        for(Map.Entry<String,String> mapping:list){ 
               System.out.println(mapping.getKey()+":"+mapping.getValue()); 
          } 
     }
View Code

 Lambda简化版

    public static void main(String[] args)
    {
        Map<String, String> map = new HashMap<String, String>();
        map.put("c", "ccccc");
        map.put("a", "daaaa");
        map.put("b", "bbbbb");
        map.put("d", "ddddd");
        
        List<Map.Entry<String, String>> list=new ArrayList<Map.Entry<String,String>>(map.entrySet());
        list.sort((o1,o2)-> o1.getValue().compareTo(o2.getValue()));
        
        for(Map.Entry<String,String> mapping:list){ 
               System.out.println(mapping.getKey()+":"+mapping.getValue()); 
          } 
    }
View Code

 

 

 

    
posted @ 2017-06-21 15:48  明-Ming  阅读(8328)  评论(0编辑  收藏  举报