zoukankan      html  css  js  c++  java
  • leetcode 数组array

    二维数组初始化:

    int[][] a = {{1,3},{2,6},{8,10},{15,18}};


    120. Triangle

    给出一个三角形(数据数组),找出从上往下的最小路径和。每一步只能移动到下一行中的相邻结点上。

    解法,自底向上

    The idea is simple.

    1.  Go from bottom to top.

    2.  We start form the row above the bottom row [size()-2].

    3.  Each number add the smaller number of two numbers that below it.

    4.  And finally we get to the top we the smallest sum.

      public int minimumTotal(List<List<Integer>> triangle) {
            for(int i = triangle.size() - 2; i >= 0; i--)
                for(int j = 0; j <= i; j++)
                    triangle.get(i).set(j, triangle.get(i).get(j) + Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1)));
            return triangle.get(0).get(0);
        }

    Boyer-Moore majority vote algorithm(摩尔投票算法)

    简介

    Boyer-Moore majority vote algorithm(摩尔投票算法)是一种在线性时间O(n)和空间复杂度的情况下,在一个元素序列中查找包含最多的元素。它是以Robert S.Boyer和J Strother Moore命名的,1981年发明的,是一种典型的流算法(streaming algorithm)。

    在它最简单的形式就是,查找最多的元素,也就是在输入中重复出现超过一半以上(n/2)的元素。如果序列中没有最多的元素,算法不能检测到正确结果,将输出其中的一个元素之一。

    当元素重复的次数比较小的时候,对于流算法不能在小于线性空间的情况下查找频率最高的元素。

    算法描述

    算法在局部变量中定义一个序列元素(m)和一个计数器(i),初始化的情况下计数器为0. 算法依次扫描序列中的元素,当处理元素x的时候,如果计数器为0,那么将x赋值给m,然后将计数器(i)设置为1,如果计数器不为0,那么将序列元素m和x比较,如果相等,那么计数器加1,如果不等,那么计数器减1。处理之后,最后存储的序列元素(m),就是这个序列中最多的元素。

    如果不确定是否存储的元素m是最多的元素,还可以进行第二遍扫描判断是否为最多的元素。

    perudocode

    • Initialize an element m and a counter i with i = 0
    • For each element x of the input sequence:
      • if i = 0, then assign m = x and i = 1
      • else if m = x, then assign i = i + 1
      • else assign i = i − 1
    • Return m

    问题1:数组中存在元素出现次数大于 ⌊ n/2 ⌋ ,求该元素

    上面方法即可

    问题2:数组中是否存在元素出现次数大于 ⌊ n/2 ⌋ 

    用上面找到的摩尔投票算法,第一遍扫描输出一个存储的元素,然后还需要进行第二遍扫描来判断元素在序列中是否确实超过n/2了。 因为一个元素超过一半,最后肯定会留下,但是最后留下的不一定超过一半,所以要扫描第二遍。

    229. Majority Element II

    求出现次数大于n/3的众数,而且限定了时间和空间复杂度,那么就不能排序,也不能使用哈希表,这么苛刻的限制条件只有一种方法能解了,那就是摩尔投票法 Moore Voting

    我们先考虑可能会有多少个众数,经过举了很多例子分析得出,任意一个数组出现次数大于n/3的众数最多有两个

    我们使用投票法的核心是找出两个候选众数进行投票,需要两遍遍历,第一遍历找出两个候选众数,第二遍遍历重新投票验证这两个候选众数是否为众数即可,选候选众数方法和前面那篇Majority Element 求众数一样,由于之前那题题目中限定了一定会有众数存在,故而省略了验证候选众数的步骤,这道题却没有这种限定,即满足要求的众数可能不存在,所以要有验证。

    public List<Integer> majorityElement(int[] nums) {
        if (nums == null || nums.length == 0)
            return new ArrayList<Integer>();
        List<Integer> result = new ArrayList<Integer>();
        int number1 = nums[0], number2 = nums[0], count1 = 0, count2 = 0, len = nums.length;
        for (int i = 0; i < len; i++) {
            if (nums[i] == number1)
                count1++;
            else if (nums[i] == number2)
                count2++;
            else if (count1 == 0) {
                number1 = nums[i];
                count1 = 1;
            } else if (count2 == 0) {
                number2 = nums[i];
                count2 = 1;
            } else {
                count1--;//不属于这两个,都要减一
                count2--;
            }
        }
        count1 = 0;
        count2 = 0;
        for (int i = 0; i < len; i++) {
            if (nums[i] == number1)
                count1++;
            else if (nums[i] == number2)
                count2++;
        }
        if (count1 > len / 3)
            result.add(number1);
        if (count2 > len / 3)
            result.add(number2);
        return result;
    }

    旋转数组的最小数字

    采用二分法解答这个问题,
    mid = low + (high - low)/2
    需要考虑三种情况:
    (1)array[mid] > array[high]:
    出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。
    low = mid + 1
    (2)array[mid] == array[high]:
    出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边
    还是右边,这时只好一个一个试 ,
    high = high - 1
    (3)array[mid] < array[high]:
    出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左
    边。因为右边必然都是递增的。
    high = mid
    注意这里有个坑:如果待查询的范围最后只剩两个数,那么mid 一定会指向下标靠前的数字
    比如 array = [4,6]
    array[low] = 4 ;array[mid] = 4 ; array[high] = 6 ;
    如果high = mid - 1,就会产生错误, 因此high = mid
    但情形(1)中low = mid + 1就不会错误

    import java.util.ArrayList;
    public class Solution {
        public int minNumberInRotateArray(int [] array) {
            int low = 0 ; int high = array.length - 1;   
            while(low < high){
                int mid = low + (high - low) / 2;        
                if(array[mid] > array[high]){
                    low = mid + 1;
                }else if(array[mid] == array[high]){
                    high = high - 1;
                }else{
                    high = mid;
                }   
            }
            return array[low];
        }
    }
    //旋转二分查找目标值
        public int search(int[] nums, int target) {
            int length=nums.length;
            if(length<=0) return -1;
            int low=0;
            int high=length-1;
            int mid=-1;
            while (low<=high){
                mid=(low+high)/2;
                if(target==nums[mid]) {
                    return mid;
                }else {
                    if(nums[mid]<nums[high]){
                        if(nums[mid]<target&&nums[high]>=target) low=mid+1;
                        else high=mid-1;
                    }else {
                        if(nums[low]<=target&&nums[mid]>target) high=mid-1;
                        else low=mid+1;
                    }
                }
            }
            return -1;
        }
    }

    任务列表(360公司2017春招真题)

    现在现在有一台机器,这台机器可以接收两种形式任务:(1)任务列表,任务列表里面有N个任务,对于第i个任务,机器在Ti时间开始执行,并在1个单位时间内做完。(2)临时任务,机器可以在任意时间接收一个临时任务,但任务列表里面的任务优先级要高于临时任务,也就是说当机器空闲的时候才会执行临时任务。

    现在机器已经接收一个任务列表。接下来会有M个临时任务,我们想知道每个临时任务何时被执行。为了简化问题我们可以认为这M个临时任务是独立无关即任务是可以同时执行的,互不影响的。

    输入
    输入数据有多组,每组数据第一行包括两个整数N和M(1<=N, M<=10^5)。
    接下来一行有N个不同数字T1,T2,T3.....TN(1<=T1
    接下来又M行,每行一个数字Qi(1<=Qi<=10^9),表示第i个临时任务的的接收时间。
    输出
    对于每个临时任务,输出它被执行的时间。
    样例输入
    5 6
    1 2 3 5 6
    3
    2
    1
    4
    5
    6
    样例输出
    4
    4
    4
    4
    7

    7

    将不能执行的时间标出来 对于每个临时任务往后找出一个可以执行的时间

        public static void main(String[] args) {
    
            Scanner cin = new Scanner(System.in);
            int n = cin.nextInt();
            int m = cin.nextInt();
            int[] gap = new int[100000];
            for (int i = 0; i < n; i++) {
                int temp = cin.nextInt();
                gap[temp] = 1;
            }
            int[] result = new int[m];
            for (int i = 0; i < m; i++) {
                int temp = cin.nextInt();
    
                for (int j = temp; j < gap.length; j++) {
                    if (gap[j] != 1) {
                        result[i] = j;
                        break;
                    }
                }
    
            }
    
            for (int i = 0; i < result.length; i++) {
                System.out.println(result[i]);
            }
    
        }

    56. Merge Intervals

    先把第一个区间加入结果集,在循环中如果更新了第一个区间的max interval[1],result的第一个interval也会随之更新

    public int[][] merge(int[][] intervals) {
            if (intervals.length <= 1)
                return intervals;
    
            // Sort by ascending starting point
            Arrays.sort(intervals, (i1, i2) -> Integer.compare(i1[0], i2[0]));
    
            List<int[]> result = new ArrayList<>();
            int[] newInterval = intervals[0];
            result.add(newInterval);
            for (int[] interval : intervals) {
                if (interval[0] <= newInterval[1]) // Overlapping intervals, move the end if needed
                    newInterval[1] = Math.max(newInterval[1], interval[1]);
                else {                             // Disjoint intervals, add the new interval to the list
                    newInterval = interval;
                    result.add(newInterval);
                }
            }
    
            return result.toArray(new int[result.size()][]);
        }
  • 相关阅读:
    20200209 ZooKeeper 3. Zookeeper内部原理
    20200209 ZooKeeper 2. Zookeeper本地模式安装
    20200209 Zookeeper 1. Zookeeper入门
    20200206 尚硅谷Docker【归档】
    20200206 Docker 8. 本地镜像发布到阿里云
    20200206 Docker 7. Docker常用安装
    20200206 Docker 6. DockerFile解析
    20200206 Docker 5. Docker容器数据卷
    20200206 Docker 4. Docker 镜像
    Combining STDP and Reward-Modulated STDP in Deep Convolutional Spiking Neural Networks for Digit Recognition
  • 原文地址:https://www.cnblogs.com/34fj/p/9310620.html
Copyright © 2011-2022 走看看