精华内容
下载资源
问答
  • 编写代码在一个整形有序数组中查找具体的某个 我们如何在一个整形数组中找到某个具体的呢?今天跟大家分享一个二分查找算法,二分查找又称折半查找。首先,假设表中元素是按升序排列,将表中间位置记录的关键字...

    编写代码在一个整形有序数组中查找具体的某个数

    我们如何在一个整形数组中找到某个具体的数呢?今天跟大家分享一个二分查找算法,二分查找又称折半查找。首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
    具体代码:

    int main()
    {
    	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//定义一个整形有序数组
    	int key = 0;//我们要查找的数
    	scanf_s("%d", &key);
    	int left = 0;//数组做下标
    	int right = sizeof(arr) / sizeof(arr[0]) - 1;//数组右下标
    	while (left <= right)//当满足时,进入循环
    	{
    		int mid = (left + right) / 2;//求出中间数的下标
    		if (arr[mid] < key)//key>arr[mid],说明key在中间数右边
    		{
    			left = mid + 1;//左下标加重新得到一个子表
    		}
    		else if (arr[mid]>key)//与上面相反
    		{
    			right = mid - 1;
    		}
    		else
    		{
    			printf("找到了,下标是:%d", mid);//找到的话,打印出下标
    			break;
    		}
    	}
    	if (left>right)//
    	
    	{
    		printf("没找到");
    	}
    	return 0;
    }
    

    运行结果;
    在这里插入图片描述
    在这里插入图片描述
    二分查找的优点是比较次数少,查找速度快,平均性能好,占用系统内存较少;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。

    展开全文
  • 给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 使用双指...

    给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
    不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

    使用双指针法, 可以将时间负责度o(n^2)的解法优化为o(n)。

    这个算法只需要遍历一次就可以得到对应数组的长度

    图解 : (官方教程
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    int[] a = new[] {1, 1, 1, 2, 3, 4};
    public void OutPutArrayLength(int[] a)
    {
    	int q = 0;
    	int p = q + 1;
    	int index = 0;
    	for (int i = 0; i < a.Length - 1; i++)
    	{
       		q = i;
       		p = q + 1;
       		if (a[q] != a[p])
       		{
          		index++;
          		int tmp = a[p];
          		a[p] = a[index];
          		a[index] = tmp;
       		}
    	}
    }
    
    return index+1;
    
    展开全文
  • Python寻找两个有序数组的中位

    千次阅读 2018-12-03 20:15:04
    有序数组中有一半的元素小于等于数组的中位数,有一半的元素大于等于中位数(如果数组中元素个数是奇数,那么这里的一半并不是严格意义的1/2) 如果我们去掉其中一个数组比中位数小的k个数,再去掉另一个...

    Python寻找两个有序数组的中位数

    审题:

    1. 找出意味着这是一个查找算法题
    2. 算法复杂度log级别,就是提示你是二分查找
    3. 二分查找实现一般为递归
      (1)递归包括递归体
      (2)终止条件

    思路:

    定理:

    1. 有序数组中有一半的元素小于等于数组的中位数,有一半的元素大于等于中位数(如果数组中元素个数是奇数,那么这里的一半并不是严格意义的1/2)
    2. 如果我们去掉其中一个数组比中位数小的k个数,再去掉另一个数组中比中位数大的k个数,得到的合并子数组的中位数和原来的中位数相同。
      eg:[1,2,3],[1,2,3] => [1,1,2,2,3,3]
      根据定理去除元素[2,3],[1,2] => [1,2,2,3]中位数没变。我用了特殊的例子解释,你可以自行换一个试一试。如果两个的数组长度不一样的时候,不能去掉各自的一半,要去掉相同的个数,下面会细说

    解题思路:

    假设两个数组的中位数分别是a[m1],b[m2]

    1. if a[m1] == b[m2] ,那么刚好有一半的元素小于a[m1],那么a[m1]就是要找的中位数。参考上面的列子
    2. if a[m1] < b[m2],根据定理1可知,这个中位数只可能出现在a[n1/2 ~ n1-1]或者b[0 ~ n2/2].也就是说合并这两个数组的中位数和原来的数组合并的数组的中位数是一样的。 根据定理2可知:
      1.数组长度一样的时候,去除掉一半是合理的。
      2.数组长度不一样,这么做中位数可能发生变化。解决方案就是去除掉相同个数的元素。why?假设n1 < n2, 两个数组就去掉n1/2个元素。那就不在是上面的范围(a[n1/2 ~ n1-1]或者b[0 ~ n2/2]),而是a[n1/2 ~ n1-1]或者b[0 ~ (-n1/2+n2-1)].
      结论就是:只能删除a的n1/2(向下取整)
    3. if a[m1] > b[m2],和上面分析类似,中位数只能出现在a的前半段或者b的后半段。也就是说a[0 ~ n1/2]和b[n1/2 ~ n2-1]的中位数和原来的中位数相同。

    参考:LeetCode参考答案

    class Solution:
        def findMedianSortedArrays(self, nums1, nums2):
            """
            :type nums1: List[int]
            :type nums2: List[int]
            :rtype: float
            """
            m, n = len(nums1), len(nums2)
            if m > n:
                nums1, nums2, m, n = nums2, nums1, n, m
            if n == 0:
                raise ValueError
    
            imin, imax, half_len = 0, m, (m + n + 1) // 2
            while imin <= imax:
                i = (imin + imax) // 2
                j = half_len - i
                if i < m and nums2[j-1] > nums1[i]:
                    # i is too small, must increase it
                    imin = i + 1
                elif i > 0 and nums1[i-1] > nums2[j]:
                    # i is too big, must decrease it
                    imax = i - 1
                else:
                    # i is perfect
    
                    if i == 0: max_of_left = nums2[j-1]
                    elif j == 0: max_of_left = nums1[i-1]
                    else: max_of_left = max(nums1[i-1], nums2[j-1])
    
                    if (m + n) % 2 == 1:
                        return max_of_left
    
                    if i == m: min_of_right = nums2[j]
                    elif j == n: min_of_right = nums1[i]
                    else: min_of_right = min(nums1[i], nums2[j])
    
                    return (max_of_left + min_of_right) / 2.0
    
    展开全文
  • 给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组 按照降序输出 [要求] 时间复杂度为O(klog⁡k)O(k \log k)O(klogk) 输入描述: 第一行三个...
    两个有序数组间相加和的Topk问题

    题目描述

    给定两个有序数组arr1和arr2,再给定一个整数k,返回来自arr1和arr2的两个数相加和最大的前k个,两个数必须分别来自两个数组

    按照降序输出

    [要求]

    时间复杂度为 O ( k log ⁡ k ) O(k \log k) O(klogk)

    输入描述:

    第一行三个整数N, K分别表示数组arr1, arr2的大小,以及需要询问的数
    接下来一行N个整数,表示arr1内的元素
    再接下来一行N个整数,表示arr2内的元素

    输出描述:

    输出K个整数表示答案

    示例1
    输入
    5 4
    1 2 3 4 5
    3 5 7 9 11
    
    输出
    16 15 14 14
    
    备注:

    1 ⩽ N ⩽ 1 0 5 1 \leqslant N \leqslant 10^5 1N105
    0 ⩽ a r r 1 i , a r r 2 i ⩽ 1 0 9 0 \leqslant arr_{1_{i}}, arr_{2_{i}} \leqslant 10^9 0arr1i,arr2i109
    保证 1 ⩽ K ⩽ 2 N 1 \leqslant K \leqslant 2N 1K2N


    题解:

    一般涉及到 TopK 问题,首先应该想到使用堆2333。

    我们可以知道 a[n-1] + b[n-1] 是整体的最大值,那么在这个最大值之后应该是哪个元素呢,应该是: m a x { a [ n − 1 ] + b [ n − 2 ] , a [ n − 2 ] + b [ n − 1 ] } max\{a[n-1] + b[n-2], a[n-2] + b[n-1]\} max{a[n1]+b[n2],a[n2]+b[n1]},它俩就是下一个可能最大值,绝不会出现比它们更大的元素。

    我们可以使用一个大根堆,每个节点保存三个元素 { s u m , i d x 1 , i d x 2 } \{sum, idx1, idx2\} {sum,idx1,idx2},且 a [ i d x 1 ] + b [ i d x 2 ] = s u m a[idx1]+b[idx2] = sum a[idx1]+b[idx2]=sum,两个下标用来表明该元素由两个数组中哪两个元素凑成的。

    选择堆顶元素,其就是整体的最大值,将其删除,然后把两个可能的最大元素插入到堆中去:

    • { a [ i d x 1 − 1 ] + b [ i d x 2 ] , i d x 1 − 1 , i d x 2 } \{a[idx1-1]+b[idx2], idx1-1, idx2\} {a[idx11]+b[idx2],idx11,idx2}

    • { a [ i d x 1 ] + b [ i d x 2 − 1 ] , i d x 1 , i d x 2 − 1 } \{a[idx1] + b[idx2-1], idx1, idx2-1\} {a[idx1]+b[idx21],idx1,idx21}

    这样进行 k 次操作后,就可以得到整体的 TopK 了。

    注意:
    1. 需要判重,因为两个节点的下标有可能相等
    2. 测试数据出现无序的情况。。。。。。

    代码:
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    #include <unordered_map>
    
    using namespace std;
    
    const int N = 100000;
    
    typedef pair<int, int> PII;
    typedef pair<int, PII> PIP;
    
    int n, k;
    int a[N], b[N];
    
    int main(void) {
        scanf("%d%d", &n, &k);
        for ( int i = 0; i < n; ++i )
            scanf("%d", a + i);
        for ( int i = 0; i < n; ++i ) 
            scanf("%d", b + i);
        sort( a, a + n );
        sort( b, b + n );
        priority_queue<PIP> heap;
        unordered_map<int, bool> hash;
        heap.push({a[n-1]+b[n-1], {n-1,n-1}});
        hash[(n - 1) * N + n - 1] = true;
        while ( k-- ) {
            auto t = heap.top();
            heap.pop();
            printf("%d ", t.first);
            int x = t.second.first, y = t.second.second;
            int key = x * N + y - 1;
            if ( y && !hash.count(key) ) {
                heap.push({a[x] + b[y-1], {x, y-1}});
                hash[key] = true;
            }
            key = (x - 1) * N + y;
            if ( x  && !hash.count(key) ) {
                heap.push({a[x-1] + b[y], {x-1, y}});
                hash[key] = true;
            }
        }
        return 0;
    }
    
    贴一个正儿八经的 O(klogk) 复杂度代码:
    #include <iostream>
    #include <vector>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    
    int a[N];
    int b[N];
    
    using PII = pair<int, int>;
    
    int main(void) {
        int n, k;
        scanf("%d%d", &n, &k);
        for ( int i = 0; i < n; ++i )
            scanf("%d", a + i);
        for ( int i = 0; i < n; ++i )
            scanf("%d", b + i);
        sort(a, a + n);
        sort(b, b + n);
        
        auto cmp = [&](const PII& lhs, const PII& rhs) {
            return a[lhs.first] + b[lhs.second] <= a[rhs.first] + b[rhs.second];
        };
        
        priority_queue<PII, vector<PII>, decltype(cmp)> heap(cmp);
        
        int r = max(0, n - k);
        for ( int i = n - 1; i >= r ; --i ) {
            heap.emplace( move(PII(i, n - 1)) );
        }
        while ( k-- ) {
            auto [x, y] = heap.top();
            heap.pop();
            printf("%d ", a[x] + b[y]);
            if ( y ) heap.emplace( move(PII(x, y-1)) );
        }
        return 0;
    }
    
    展开全文
  • 每日算法(十五)-java给定一个有序数组删除其中重复元素,只保留一个,并返回新数组的长度 Example 2: Given nums = [0,0,1,1,1,2,2,3,3,4], Your function should return length = 5, with the first five ...
  • 请你找出这两个有序数组的中位,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 示例 1: nums1 = [1, 3] nums2 = [2] 则中位是 2.0 示例 2: nums1 = [1, 2] ...
  • 前言 大学毕业以来一直想提升自己...但是学习这过程知识阅读、记忆和短期的练习是不够的,还需要总结与复习的过程,才能真正把知识变成自己的东西(自己十几年学习总结的拙见=。=)。所以就想着通过系列技术博...
  • 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明...
  • 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 示例: ...
  • 给你一个有序数组 nums,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明: 为...
  • 【LeetCode每日一题】80. 删除有序数组中的重复项 II今日题目80题,每日一题微信交流群可以点击右下角:合作转载->联系我,拉你入群。题目:给你一个有序数组 nums ,请...
  • 给你一个有序数组 nums,请你原地删除重复出现的元素,使每个元素只出现 一次,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空 间的条件下完成。 分析 由于...
  • 2)有两个排好序的数组,找到其中第k个数 以及扩展: 3)有M个排好序的数组,找到其中第k个数 为了消除歧义,解释如下: 有两个数组,A(a1, a2,...,an) 和 B(b1, b2,...,bm),分别按升序排列,即a1 可以看到,1...
  • 请你找出这两个有序数组的中位,并且要求算法的时间复杂度为 O(log(m + n))。 你可以假设 nums1 和 nums2 不会同时为空。 输入示例: 示例 1: nums1 = [1, 3] nums2 = [2] 则中位是 2.0 示例 2: nums1 = ...
  • 个有序数组找第k大的

    千次阅读 2014-10-30 21:24:39
    问题描述: 两个有序数组一个
  • 题目:给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 ...
  • 问题:两已经排好序的数组,找出两个数组合并后的中位(如果两个数组的元素数目是偶数...算法1:最简单的办法就是把两个数组合并、排序,然后返回中位即可,由于两个数组原本是有序的,因此可以用归并排序中的m
  • 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 给定数组 nums =...
  • 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下
  • 有序数组其实就是数组的进化版,和数组唯一的区别就是“有序”这两字,就是指在这数组当中的所有数据,必须按照一定的顺序来排列,即便是插入新数据或者删除原有数据,仍然要按照既定规则来排序;而普通的数组是...
  • 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明: 为...
  • 一个有序数组,其中包含重复的元素,去除重复的数字然后输出; 解决: 1.用指针比较方便,这里用数组下标来解决吧; 2.tmp类似指针指向不重复元素的最后一位; 3.num类似指针指向删除重复元素后的数组的最后一...
  • 求多个有序数组的中位

    万次阅读 2012-09-15 10:57:47
    题目的意思是如果多个有序数组能在一起排序,则取位置为中间的数字,如果有奇数个数字则中位只有一个;若为偶数个则有两个,一般取第一个,也称下中位。但不能把组合在一起做插入或快速排序,因为数据可能是海量...
  • LeetCode-寻找两个有序数组的中位题目回顾题解cpp 代码实现 题目回顾 传送门 给定两大小为 m 和 n 的有序数组 nums1 和 nums2。 请你找出这两个有序数组的中位,并且要求算法的时间复杂度为 O(log(m + n))。 ...
  • 思路1:将两个数组按照索引i与索引j切分为左右两部分,左半部分与右半部分的元素数量相同,并且寻找到左半部分最大值小于右半部分最小值的位置,中位就在附近,具体的根据总长度是偶数/奇数确定。寻找索引的过程...
  • LeetCode的第80题,有序数组去重II(Remove Duplicates from ...其实从题目的标题当中我们已经可以得到很多信息了,实际上也的确如此,这题的题面和标题八九不离十,需要我们对一个有序的数组进行去重。不过去重的条件是
  • 有序数组的二分查找--Java实现

    千次阅读 2018-05-16 09:40:59
    二分查找又称折半查找,它是种效率较高的查找方法。1、折半查找的算法思想是将数列按有序化(递增或递减)排序,查找过程采用跳跃方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元素,...
  • 简单粗暴,先将两数组合并,两个有序数组的合并也是归并排序中的部分。然后根据奇数,还是偶数,返回中位。 代码 class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int...
  • 目的是为了更方便快捷的记忆和回忆算法重点(不用每次都重复看题解),毕竟算法不是做了遍就能完全记住的.所以本文适合已经知道解题思路和方法,想进一步加强理解和记忆的朋友,并不适合第次接触此题的朋友(可以根据...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 85,582
精华内容 34,232
关键字:

删除一个数得到有序数组