zoukankan      html  css  js  c++  java
  • SortAndFind(排序与查找)

    1.给定两个排序后的数组A和B,其中A的末端有足够的缓冲空容纳B。编写一个方法,将B合并入A并排序。

    思路:从数组A和B的末端元素开始,将最大的元素放到数组A的末端。

        public static void merge(int[] a, int[] b, int lastA, int lastB) {
            int indexA = lastA - 1;
            int indexB = lastB - 1;
            int indexMerged = lastB + lastA - 1;
            while (indexA >= 0 && indexB >= 0) {
                if (a[indexA] > b[indexB]) {
                    a[indexMerged] = a[indexA];
                    indexMerged--;
                    indexA--;
                } else {
                    a[indexMerged] = b[indexB];
                    indexMerged--;
                    indexB--;
                }
            }
            while (indexB>= 0) {
                a[indexMerged] = b[indexB];
                indexMerged--;
                indexB--;
            }
        }
    View Code

    2.编写一个方法,对字符串数组进行排序,将所有变位词排在相邻的位置。

    解法一:套用一种标准排序算法,比如归并排序或快速排序,并修改比较器(comparator)。这个比较器用来指示两个字符串互为变位词就是相等的。

    检查两个词是否为变位词的方法?(1)数一数每个字符串中各个字符出现的次数,两者相同则返回true。(2)对字符串进行排序,若两个字符串互为变位词,排序后就相同。

        //比较器实现代码
        public class AnagramComparator implements Comparator<String> {
            public String sortChars(String s) {
                char[] content = s.toCharArray();
                Arrays.sort(content);
                return new String(content);
            }
            
            public int compare(String s1, String s2) {
                return  sortChars(s1).compareTo(sortChars(s2));
            }
        }
        //利用这个比较器对数组进行排序
        Arrays.sort(array, new AnagramComparator());
    View Code

    这个算法的时间复杂度是O(nlogn)。

    解法二:使用散列表将排序后的单词映射到它的一个变位词列表。例:acre会映射到列表{acre, race, care}。一旦将所有同为变位词的单词分组在一起,就可以将它们放回到数组中。

        public static void sort(String[] array) {
            Hashtable<String, LinkedList<String>> hash = new Hashtable<String, LinkedList<String>>();
            //将同为变位词的单词分在同一组
            for (String s : array) {
                String key = sortChars(s);
                if (!hash.containsKey(key)) {
                    hash.put(key, new LinkedList<String>());
                }
                LinkedList<String> anagrams = hash.get(key);
                anagrams.push(s);
            }
            //将散列表转换为数组
            int index = 0;
            for (String key : hash.keySet()) {
                LinkedList<String> list = hash.get(key);
                for (String t : list) {
                    array[index] = t;
                    index++;
                }
            }        
        }
    
        public static String sortChars(String s) {
            char[] content = s.toCharArray();
            Arrays.sort(content);
            return new String(content);
        }
    View Code

    3.给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次,次数不详。请编写代码找出数组中的某个元素。可以假定数组元素原先是按从小到大的顺序排列的。

    解法:《九章算法》chapter two search-in-rotated-sorted-array

    4.设想你有一个20GB的文件,每一行一个字符串。请说明将如何对这个文件进行排序。

    思路:只将部分数据载入内存。将整个文件划分成许多块,每个块xMB,其中x是可用的内存大小。每个块各自进行排序,然后存回文件系统。各个块一旦完成排序,便将这些块逐一合并在一起,最终就能得到全都排好序的文件。这个算法被称为外部排序(external sort)。

    5.有个排序后的字符串数组,其中散布着一些空字符串,编写一个方法,找出给定字符串的位置。

    思路:如果没有那些空字符串,就可以直接使用二分查找法。比较待查找字符串str和数组的中间元素,然后继续搜索下去。针对此题,可对二分查找法稍作修改,所需的修改就是与mid进行比较的地方,如果mid为空字符串,就将mid换到离它最近的非空字符串的位置。

        public static int findString(String[] a, String key) {
            int left = 0;
            int right = a.length - 1;
            while (left <= right) {
                int mid = (left + right) / 2;
                while (mid < right && a[mid] == "") {
                    mid++;
                }
                while (mid > left && a[mid] == "") {
                    mid--;
                }
                
                if (key.equals(a[mid])) {
                    return mid;
                } else if (key.compareTo(a[mid]) < 0){//key小于a[mid]
                    right = mid - 1;//搜索左半边
                } else {
                    left = mid + 1;
                }
            }
            return -1;
        }
    View Code

    6.给定M* N矩阵,每一行、每一列都按升序排列,请编写代码找出某元素。

    解法:《九章算法》chapter two search-a-2d-matrix

    7.有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点、轻一点。已知马戏团每个人的高度和重量,请编写代码计叠罗汉最多能叠几个人。

    问题实质:给定一个列表,每个元素由一对项目组成。找出最长的子序列,其中第一项和第二项均以非递减的顺序排列。

    8.假设你正在读取一串整数。每隔一段时间,你希望能找出数字x的秩(小于或等于x的值的数目)。请实现数据结构和算法支持这些操作。也就是说,实现track(int x)方法,每读入一个数字都会调用该方法;以及getRankOfNumber(int x)方法,返回值为小于或等于x的元素个数(不包括x本身)。

  • 相关阅读:
    网络编程之UDP
    深入浅出Object.defineProperty()
    Vue知识点总结
    JS基础-垃圾回收机制与内存泄漏的优化
    JS基础-作用域
    ES6知识点
    JS基础-this
    JS基础-事件循环机制
    JS基础-事件
    JS基础-事件队列
  • 原文地址:https://www.cnblogs.com/struggleli/p/8244012.html
Copyright © 2011-2022 走看看