丢失的珠子

1 丢失的珠子

1.1 问题描述

(1) 问题描述:何老板有一盒珠子共n颗,编号1到n。他一不小心将盒子打翻,所有珠子都散落在地。他一颗一颗地把珠子捡起来,每捡一颗就记录下当前这颗珠子的编号。捡完以后发现少了两颗,请你快速找出少了哪两颗珠子。
(2) 输入格式:第一行,一个整数n;接下来一行,n-2个空格间隔的整数,表示何老板捡起来的珠子的编号。
(3) 输出格式:一行,由小到大排列的两个整数,表示丢失的两颗珠子的编号。
(4) 样例输入:
7
4 1 7 2 5
样例输出:
3 6
(5) 提示:对于30%的数据,有n<=1,000;对于100%的数据,有n<=1,000,000
(6) 基本要求:编程语言不限,提交技术报告(包括算法描述、算法的时间复杂度与空间复杂度分析、源代码、实验结果与分析)

1.2 编程实现

1.2.1 算法思想

(1)算法1:
首先将何老板捡起来的珠子编号依次存入长度为n+1的一维数组中,并且珠子编号和数组元素下标一一对应。然后再从下标1开始遍历整个数组,找到数组元素数据为0的下标,即为丢失的珠子编号。
算法1代码如下:

import java.util.*;
public class Looking_beads1 {
  public static void main(String [] args) {
      Scanner sc = new Scanner(System.in);
      int n =sc.nextInt();
      int [] arr = new int[n+1];
      int temp;
      
      for(int i=1;i<n-1;i++) {
          temp = sc.nextInt();
          arr[temp]=temp;
      }
      for(int j=1;j<n+1;j++) {
          if(arr[j]==0)
            System.out.print(j+" ");  
      }
      sc.close();
  }
}

从上述代码中可以看出,该算法使用了一次n-1次循环和一次n次循环,因此该算法时间复杂度为O(n)。另外,该算法定义了一个一维数组,所以其空间复杂度为O(n)空间复杂度还是相对较高。下面介绍一种不使用数组的算法。
(2)算法2:
从问题描述中可以得知该串珠子的编号是有序的,那么就可以借助等差数列的思想,先求出所有珠子的编号和以及平方和,再求出n-2颗珠子的编号和以及平方和,进而得到丢失珠子的编号和以及平方和。最后利用解方程的思想得到唯一解。
算法2代码如下:

import java.util.*;
public class Looking_beads2 {
  public static void main(String [] args) {
      Scanner sc = new Scanner(System.in);
      int n =sc.nextInt();
      int sum   = 0;
      int s_sum = 0;
      int temp  = 0;
      
      for(int i=1;i<=n;i++) {
          sum   += i;
          s_sum += i*i;
      }
      
      for(int j=1;j<=n-2;j++) {
          temp = sc.nextInt();
          sum -= temp;
          s_sum -= temp*temp;
      }
      
      for(int k=1;k<=Math.min(sum, n);k++) {
          if(k*k+(sum-k)*(sum-k) == s_sum) {
              System.out.println(k+" "+(sum-k)); 
              break;
          }  
      }
      sc.close();
  }
}

从上述代码中可以看出,最坏情况下需要使用三次n次循环,所以时间复杂度还是O(n),但是由于没有使用数组,那么空间复杂度只有O(1)。算法2相较于算法1空间复杂度降低了。

1.2.2 实验结果

(1)算法2测试样例1:
7
4 1 7 2 5
测试结果如图1所示:
测试结果1

(2)算法2测试样例2:
20
19 8 10 9 18 12 7 4 13 15 17 6 3 1 14 16 20 2
测试结果如图2所示:
测试结果2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值