提前批笔试一道算法题的Java实现
题目描述
这是2021广联达校招提前批笔试算法题之一。
我们希望一个序列中的元素是各不相同的,但是理想和显示往往是有差距的。现在给出一个序列A,其中难免有相同的元素,现在提供了一种变化方式,使得经过若干次操作后一定可以得到一个元素各不相同的序列。
这个操作是这样的,令x为序列中最小的重复数字,你需要删除序列左数第一个x,并把第二个x替换为2*x。请你输出最终的序列。
例如原序列是[2,2,1,1,1],一次变换后变为[2,2,2,1],两次变换后变为[4,2,1],变换结束。
输入描述
输入第一行包含一个正整数n,表示序列的长度为n。(1<=n<=50000)
第二行有n个整数,初始序列中的元素。(1<=a_i<=10^8)
输出描述
输出包含若干个整数,即最终变换之后的结果。
算法思路
通过HashSet和HashMap实现重复元素存入集合以及元素出现次数的统计;
递归思想。
算法实现
import java.util.*;
/**
* @author Chiaki
*/
public class Main {
public static void main(String[] args) {
int n = 6;
int[] arr = {1,1,2,2,4,4};
long s = System.currentTimeMillis();
int[] res = getArray(n, arr);
long e = System.currentTimeMillis();
System.out.println("耗时:" + (e - s) + "ms");
System.out.print("[");
for (int i = 0; i < res.length; i++) {
if (i < res.length - 1) {
System.out.print(res[i] + ",");
} else {
System.out.print(res[i] + "]");
}
}
System.out.println();
}
/**
* 按规则处理数组并返回新的无重复元素的数组
* @param n 数组长度
* @param arr 初始数组
* @return 无重复元素的数组
*/
public static int[] getArray(int n, int[] arr) {
// 递归停止条件:只有一个元素直接返回无需进行后续操作
if (n == 1) {
return arr;
}
List<Integer> list = new LinkedList<>();
Set<Integer> set = new HashSet<>();
Map<Integer,Integer> map = new HashMap<>(n);
// 遍历数组
for (int i : arr) {
// 数组值放入链表方便操作
list.add(i);
// 利用HashSet判断元素重复
// 并统计元素出现次数放入HashMap
if (!set.add(i)) {
int count = map.get(i);
count++;
map.put(i, count);
continue;
}
map.put(i, 1);
}
// 递归停止条件:HashSet元素个数与数组长度相同
if (set.size() == n) {
return arr;
}
// 将HashSet清空用来存放重复的元素
set.clear();
for (Integer i : map.keySet()) {
if (map.get(i) > 1) {
set.add(i);
}
}
// 按规则去重 迭代停止条件:HashSet为空
while (!set.isEmpty()) {
// 从最小的重复元素开始
int minValue = Collections.min(set);
// 定义计数器
int count = 1;
// 遍历链表
for (int i = 0; i < list.size(); i++) {
// 碰到重复元素的第一个时赋值为0 计数器自增
if (list.get(i).equals(minValue) && count == 1) {
list.set(i, 0);
count++;
}
// 碰到重复元素的第二个时按要求赋值 计数器自增
if (list.get(i).equals(minValue) && count == 2) {
list.set(i, 2 * list.get(i));
count++;
}
}
// 操作结束后移除HashSet的当前重复元素并继续迭代
set.remove(minValue);
}
// 将链表中赋值为0的元素删除
list.removeIf(s -> s.equals(0));
// 剩下的元素存放到数组作为结果
int[] res = new int[list.size()];
for (int i = 0; i < res.length; i++) {
res[i] = list.get(i);
}
// 另外一种简单写法
/*int[] res = list.stream().mapToInt(Integer::valueOf).toArray();*/
// 递归调用
return getArray(res.length, res);
}
}
运行结果
耗时:33ms
[2,8,4]
提前批笔试一道算法题的Java实现的更多相关文章
- 常见排序算法题(java版)
常见排序算法题(java版) //插入排序: package org.rut.util.algorithm.support; import org.rut.util.algorithm.Sor ...
- 每天一道算法题(4)——O(1)时间内删除链表节点
1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...
- [2]十道算法题【Java实现】
前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...
- 从一道算法题实现一个文本diff小工具
众所周知,很多社区都是有内容审核机制的,除了第一次发布,后续的修改也需要审核,最粗暴的方式当然是从头再看一遍,但是编辑肯定想弄死你,显然这样效率比较低,比如就改了一个错别字,再看几遍可能也看不出来,所 ...
- 【每天一道算法题】时间复杂度为O(n)的排序
有1,2,……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且一次只能交换两个数. 这个是以前看到的算法题,题目不难.但是要求比较多,排序算法中,时间 ...
- 大公司面试经典数据结构与算法题C#/Java解答
几个大公司(IBM.MicroSoft and so on)面试经典数据结构与算法题C#解答 1.链表反转 我想到了两种比较简单的方法 第一种是需要开一个新的链表,将原链表的元素从后到前的插入到新链表 ...
- 每天一道算法题-leetcode136-只出现一次的数字
前言 打卡第一天 2019.10.26日打卡 算法,即解决问题的方法.同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的.这就需要我们学习算法,找出哪个算法更好. 大家都知道 ...
- 一道算法题加深我对C++中map函数的理解
一.一道题目引发我对map函数的考量 首先是题目大意:有n个银行,a[i]表示这个人在第i个银行有a[i]块钱(可以是负数),所有银行的钱加起来正好是0.每次只能在相邻的银行之间转账,问最少要转多少次 ...
- 【每天一道算法题】Numeric Keypad
题目描述 The numberic keypad on your mobile phone looks like below: 123 456 789 0 suppose you are hold ...
随机推荐
- OSCP Learning Notes - Exploit(1)
Gaining Root with Metasploit Platform: Kali Linux, Kioptrix Level 1 1. Find the IP of Kioptirx nmap ...
- react实战 : 用矩阵思想做一个自适应布局容器组件
需求是这样的. 有一个需要显示若干方块型元素的小区域 数量比较少的时候显示一排 数量比较多的时候显示两排 用 grid 不好,因为当数量为奇数的时候需要两排里面的元素都乖乖的居中显示. 用 flex ...
- React Native 报错 Error: spawn EACCES 权限
权限不足,运行命令修改权限 chmod android/gradlew
- IntelliJ IDEA:文件的路径本该是”\“,却变成了”¥“
修改字体导致的, 有些字体中是用¥替换掉\的,所以,修改到合适的字体就好了
- 【Nginx】如何实现Nginx的高可用负载均衡?看完我也会了!!
写在前面 不得不说,最近小伙伴们的学习热情是越来越高,不断向冰河提出新的想学习的技术.这不,又有小伙伴问我:冰河,你在[Nginx专题]写的文章基本上都是Nginx单机版的,能不能写一篇关于Nginx ...
- apache 基本配置
1.1 ServerRoot 配置 [ServerRoot "" 主要用于指定Apache的安装路径,此选项参数值在安装Apache时系统会自动把Apache的路径写入.Windo ...
- Python第一次实验
''' 计算 1.输入半径,输出面积和周长 2.输入面积,输出半径及周长 3.输入周长,输出半径及面积 ''' # # 1.输入半径,输出面积和周长 # from math import pi # # ...
- PHP ignore_user_abort() 函数
实例 设置为 false(默认)- 与客户机断开会终止脚本的执行: <?phpignore_user_abort();?>高佣联盟 www.cgewang.com 上面代码的输出如下: 0 ...
- js 读取word和txt(react版) + 正则分割段落
show the code 前提:需要mammoth包~ import React, { useState, useReducer } from 'react'; import { Button, A ...
- lamp架构搭建
目录 1. LAMP架构介绍 2.web服务器工作流程 2.1 cgi与fastcgi 2.2 httpd与php结合的方式 2.3 web工作流程 3. lamp平台搭建 3.1 安装httpd 3 ...