算法练习-排序哈希数组相关算法

一、二分查找-I

        请实现无重复数字的升序数组的二分查找

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param nums int整型vector 
     * @param target int整型 
     * @return int整型
     */
    int search(vector& nums, int target) {
        if(nums.empty()) return -1;
        int left = 0;
        int right = nums.size() -1;
        while(left <= right) { // 为啥需要 等于 = 
            int mid = (left + right) / 2;
            if(target == nums[mid]) {
                return mid;
            }
            else if(target < nums[mid]) {
                right = mid-1;
            }
            else if(target > nums[mid]) {
                left = mid + 1;
            }
        }
        return -1;
    }
};

二、旋转数组的最小数字

        有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值

class Solution {
public:
    int minNumberInRotateArray(vector rotateArray) {
        if (rotateArray.empty()) return -1;
        int left = 0;
        int right = rotateArray.size() -1;
        // 3 4 5 , 1 2
        // 4 5 ,1 2 3
        while (left < right) { //终止条件是 left == right,表示区间只有一个元素
            if(rotateArray[left] < rotateArray[right]) {
                return rotateArray[left];
            }
            int mid = (left + right)/2;
            if(rotateArray[mid] > rotateArray[left]) {
                left = mid + 1;
            }
            else if (rotateArray[mid] < rotateArray[left]) {
                right = mid;
            }
            else if (rotateArray[mid] == rotateArray[left]) { //相等的话,不好判断,这个时候需要缩小范围
                left += 1;
            }
        }
        return rotateArray[left];
    }
};

三、二维数组中的查找

        在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数

        

class Solution {
public:
    bool Find(int target, vector > array) {
        if(array.size() == 0) return false;
        int m = 0;
        int n = array[0].size() -1;
        while(m <= array.size()-1  && n >= 0) {
            if(array[m][n] == target) return true;
            else if(array[m][n] > target) { //大于target
                n--;
            }
            else if(array[m][n] < target) {
                m++;
            }
        }
        return false;
    }
};

四、合并两个有序的数

给出一个有序的整数数组 A 和有序的整数数组 B ,请将数组 B 合并到数组 A 中,变成一个有序的升序数组

class Solution {
public:
    void merge(int A[], int m, int B[], int n) {
        int i = m - 1;
        int j = n - 1;
        int k = m + n -1;
        while(i >= 0 && j >= 0) {
            if(A[i] > B[j]) {
                A[k] = A[i];
                i--;
                k--;
            }
            else if(A[i] <= B[j]) {
                A[k] = B[j];
                k--;
                j--;
            }
        }
        while(j >= 0) { // 表示B数组 没有迁移ok 还有部分数据没迁移  
            A[k--] = B[j--];
        }

    }
};

五、数组中的逆序对

 (归并排序)分治算法

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007

        

class Solution {
public:
    const int MOD = 1e9 + 7;
    vector tmp; //全局数组
    int InversePairs(vector data) {
        int n = data.size();
        tmp = vector(n); //初始化数组tmp
        return merge_sort(data, 0, n - 1);
    }

    int merge_sort(vector& data, int left, int right) {
        if (left == right) return 0; //递归终止条件
        int mid = (left + right) >> 1;

        int count = 0;
        int leftCount = merge_sort(data, left, mid);
        int rightCount = merge_sort(data, mid+1, right);
        int k = 0, i = left, j = mid + 1;
        while (i <= mid && j <= right) {
            if (data[i] <= data[j]) tmp[k++] = data[i++];
            else {
                tmp[k++] = data[j++]; 
                count += mid - i + 1;
                count %= MOD; //这个地方一定要取mod 不然大数编译不过
            }
        }
        while (i <= mid)  tmp[k++] = data[i++];
        while (j <= right)    tmp[k++] = data[j++];
        int copyindex = 0;
        for (i = left;i <= right; i++) { //tmp是辅助数组,每次需要更新数据给data
            data[i] = tmp[copyindex++];
        }
        return (count + leftCount + rightCount) % MOD;
    }
};

六、最小的K个数

        给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)

class Solution {
  public:
    vector GetLeastNumbers_Solution(vector input, int k) {

        vector res;
        if (k == 0) {
            return res;
        }
        if(k >= input.size()) return input;
        int left = 0;
        int right = input.size() - 1;
        while (left <= right) {
            int partion = quick_sort_partion(input, left, right);
            if (partion + 1 == k) {
                return vector({input.begin(), input.begin() + k});
            } else if (partion + 1 < k) {
                left = partion + 1;
            } else if (partion + 1 > k) {
                right = partion - 1;
            }
        }
        return res;

    }
    int quick_sort_partion(vector& input, int left, int right) {
        
        int val = input[right];
        int idex = left - 1; //new 一个哨兵
        for (int i = left; i < right; i++) {
            if (input[i] < val) {
                idex ++;
                swap(input[idex], input[i]);
            }
        }
        idex ++;
        swap(input[idex], input[right]);
        return idex;
    }
};

七、字典树

        请写出字典树的构造和搜索

struct Node{
    bool isEnd;
    int countnum;
    map childs;
    Node(){
        isEnd = false;
        countnum = 0;
    }
}
class Solution {
public:
    /**
     * 
     * @param operators string字符串vector> the ops
     * @return string字符串vector
     */
    Node* root = new Node();
    void inserWord(string word) {
        Node* node = root;
        for(char c : word) {
            if(node->childs.find(c) == node->childs.end()) { // not find 
                Node* new_node = new Node();
                node->childs[c] = new_node;
                node = new_node; //移到下一个位置
            }
            else { //find child
                node = node->childs[c];
            }
            node->childs[c]->countnum += 1;
        }
        node->isEnd = true;
    }

    bool searchTrie(string word) {
        Node* node = root;
        for(char item : word) {
            if(node->childs.find(c) == node->childs.end()) {
                return false;
            }
            node = node->childs[c];
        }
        return node->isEnd;
    }
};

你可能感兴趣的:(算法,数据结构,排序算法)