zoukankan      html  css  js  c++  java
  • 算法题-数组算法题

    题一:二分查找法-Java:用于有序数组

    //实验数据
    int[] arr = {3,21,34,46,55,71,74,80,97};
    

     代码:

    public int findIndex(int value, int[] arr) {
            // arr是有序数组
            // value是目标值
            int min = 0; //最大值,最小值的索引值
            int max = arr.length - 1;
            int mid = (min + max) / 2;
            while (arr[mid] != value) {
                if (arr[mid] > value) {
                    max = mid - 1;
                } else if (arr[mid] < value) {
                    min = mid + 1;
                }
                mid = (min + max) / 2;
                if (min > max) return -1;//如果最小索引大于最大索引证明没有找到这个value,要退出循环
            }
            return mid;//返回索引
        }
    

     题二:给定一个数组,写一个函数,将数组中的0都挪到数组的末尾,而维持其他非0元素的相对位置

    //实验数据
    int[] nums = {0,1,0,3,12};
    //排序后
    nums = {1,3,12,0,0}
    

    思路:将所有非0元素拿出来,放在按顺序放在一个数组中,然后将最后的位置全部塞进0

    public ArrayList moveZero(int[] nums) {
            ArrayList arrayList = new ArrayList();
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] != 0) {
                    arrayList.add(nums[i]);
                }
            }
            int diff = nums.length - arrayList.size();
            if (diff == 0) {
                return arrayList;
            } else {
                for (int i = 0; i < diff; i++) {
                    arrayList.add(0);
                }
                return arrayList;
            }
        }
    

     思路二:遍历所有数组,将非0元素都放在前K位,剩余的都填充0

    public int[] moveZero2(int[] nums) {
            int k = 0;//在数组nums中,[0...k) 均为非0元素
            //思路:在遍历的[0...i]个元素的数组中,所有的非0元素都按照顺序在[0...k)中
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] != 0) { //如果是非0元素,将该元素放在k位置
                    nums[k] = nums[i];
                    k++; //k++
                }
            }
            //将剩余位置,都放置为0
            for (int i = k; i < nums.length; i++) {
                nums[i] = 0;
            }
            return nums;
        }
    

     题目三:给n个元素的数组,元素取值只有0,1,2三种可能,请为这个数组进行排序

    思路一:使用计数排序,适用于元素个数非常有限的情况。遍历数据0,1,2的分别的元素个数,然后按照数值大小,在对应的位置分别放置多少个元素即可

    public int[] sortColors(int[] nums) {
            int[] counts = {0, 0, 0};
            // 遍历数组,查出数值个数
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] == 0) {
                    counts[0]++;
                } else if (nums[i] == 1) {
                    counts[1]++;
                } else if (nums[i] == 2) {
                    counts[2]++;
                } else {
                    return null;
                }
            }
            int index = 0;
            for (int i = 0; i < counts.length; i++) { //按照顺序塞入值
                for (int j = 0; j < counts[i]; j++) {
                    nums[index] = i;
                    index++;
                }
            }
            return nums;
        }
    

     思路二:三路快排,只需遍历一次即可: 将数组分为三部分,第一部分全是0 ,第二部分全是1,第三部分全是2。对第二部进行遍历:如果值=1,则往后遍历一位;如果值=2,将第三部分的左侧边界往左移动一位,并将i和左侧边界值交换位置(放在第三部分的最前端),i的值不变;同理,如果值=0,将第一部分的右侧值往右移动一位,并将i和右侧边界交换位置,(放在第一部分的最右端),i的值不变

    public int[] sortColors2(int[] nums) {
            // 分为三部分,第一部分全是0 ,第二部分全是1,第三部分全是2
            //初始化索引值
            int zero = -1;//nums[0,zero] 第一部分
            int two = nums.length;//nums[two,length-1] 第三部分
    
            for (int i = 0; i < two; ) {
                if (nums[i] == 1) {
                    i++;
                } else if (nums[i] == 2) {
                    two--; //第三部分的左侧边界,往左减一位
                    swap(nums, two, i); //将i和two交换位置
                } else if (nums[i] == 0) {
                    zero++; //第一部分的右侧边界,往右加一位
                    swap(nums, zero, i);
                } else {
                    return null;
                }
            }
            return nums;
        }
    
    // 交换数组元素
        public static void swap(int[] array, int x, int y) {
            int xx = array[x];
            int yy = array[y];
            array[x] = yy;
            array[y] = xx;
        }
    

     题四:在n长度的数组中,找到第k大的数值

    题五:给定一个有序整型数组和整型数target,在数组中找两个元素,使其相加和为target,并返回开两个元素的索引

    int[] nums = {2,7,11,15};
    int target = 9;
    //结果返回的索引就是:1,2(索引从1开始算)
    

    思路:使用二分查找,nums[i] 在剩余数组(也是有序的)中,寻找target-nums[i] (每一次遍历,都使用一次二分查找)

    思路二:对撞指针,(双指针)一个指针在数组首,一个指针在数组尾,两个指针不停的往中间移动 O(n)

    public int[] twoSum(int[] arr, int target) {
            if (arr.length < 2) return null;
            int l = 0;
            int r = arr.length - 1;
            int res[] = {0, 0};
            while (l < r) {
                if ((arr[l] + arr[r]) == target) {
                    res[0] = l + 1;
                    res[1] = r + 1;
                    return res; //返回索引数组
                } else if ((arr[l] + arr[r]) < target) {
                    l++; //最左侧往右移一位
                } else {
                    r--; //最右侧往左移一位
                }
            }
            throw null; //如果没有找到,抛出异常
        }
    

    题六:给定一个数组和数字s,找到数组中的最短连续子数组,使得连续子数组的数字和sum>=s,返回这个最短子数组的长度

    //实验数据
    int[] nums={2,3,1,2,4,3};
    int s = 7;
    //输出结果:子数组[3,4],长度为2
    

     思路:滑动窗口,子数组[l,r],当子数组的和<s时,将子数组的右侧往右移动,子数组增加一位;当子数组的和>=s时,将子数组的左侧往右移一位,子数组减少一位。

     public int minSubArr(int[] nums, int s) {
            int l = 0, r = -1; //nums[l...r]是我们的滑动窗口
            int sum = 0;
            int res = nums.length + 1;
    
            while (l < nums.length) { //左边界 < 长度
                if (r + 1 < nums.length && sum < s) { //当前窗口的和 <s
                    r++; //将右边界,往右移动,增加一位
                    sum += nums[r];
                } else {
              l++; //将左边界,往右移动,减少一位 sum -= nums[l]; } if (sum >= s) { res = min(res, r - l + 1); } } if (res == nums.length + 1) { //如果没有,则返回0 return 0; } return res; } //求最小值 public int min(int i, int j) { if (i < j) { return i; } else { return j; } }

     题七:寻找字符串中,没有重复字母的最长子字符串

    //示例数据:
        "abcabcbb" -> "abc"
        "nnnnn" -> "n"
        "pwwkew" -> "wke"
    

     思路:滑动窗口 ,滑动窗口的长度并不是固定不变的。每次对比下一个字符是否出现在子字符串时,使用一个频率数组,记录每个字符在子字符串中出现的频率。如果为0,那就代表没有在子字符串中出现过;如果非0,就代表出现过

  • 相关阅读:
    使用Docker在本地搭建Hadoop分布式集群
    微博推荐 第三个map 源码
    对象
    http无状态(stateless)
    理解http的无连接
    http响应报文之首部行
    http响应报文之状态行
    http响应报文
    http请求报文之首部行
    http请求之请求数据
  • 原文地址:https://www.cnblogs.com/starstarstar/p/11194991.html
Copyright © 2011-2022 走看看