昨晚刚刚写的几道算法题,难度也还行,就是全部AC有些困难,当时第一题AC、第二题AC 60%,第四题AC 40%,第五题没有时间写完了,这个应该全部AC了;其中第三题没有写出来

1,是否存在符合规范的有效号码

  某个国家的电话号码规范为:①以8开头;②长度为11位

  现在给出任意长度的一串数字,判断是否可以通过从头部或者尾部连续删除获得一串符合规范的电话号码?

  下面的代码是我第一次就写好的、后期没有优化的,感觉也没什么可以优化的空间了【使用subString还可以在缩小搜索范围】,这个题目一次通过

package com.cnblogs.mufasa.Main1;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
//0,测试 //1,输入
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();
for(int i=0;i<t;i++){
sc.next();
String str=sc.next();
int loc=str.indexOf("8");
if(loc!=-1&&str.length()-loc>=11){
System.out.println("YES");
}else{
System.out.println("NO");
}
} //2,处理 //3,输出 }
}
/*
4
8
8888888888888
8
18111111
13
18111111111111
10
11118111111 */

2,完成任务的最小耗时是多少

  有M个程序员【M为偶数】,每个程序员的拖延症拖延时间为Ti,同时有M/2个编程任务,每个编程任务需要两个程序一起解决,先求解全部任务的最小拖延耽误时间是多少?【两个程序员拖延时间相加为每个任务的拖延时间】

  我的第一次解答编程为:【在原有基础上,自己思考了一些测试用例检查出来没有全部AC的部分原因】

package com.cnblogs.mufasa.Main2_1;

import java.util.Arrays;
import java.util.Scanner; class Node implements Comparable<Node>{
int num;
int time;
public Node(int num,int time){
this.num=num;
this.time=time;
} @Override
public int compareTo(Node o) {
return time-o.time;
}
} public class Main {
public static void main(String[] args) {
//0,测试 //1,输入
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
Node[] arr=new Node[n];
for(int i=0;i<n;i++){
int num=sc.nextInt();
int time=sc.nextInt();
arr[i]=new Node(num,time);
} //2.1,处理
Arrays.sort(arr); //2.2,处理
int x=0,y=n-1,maxTime=0;
while (x!=y&&x+1!=y){
if(arr[x].time+arr[y].time>maxTime){
maxTime=arr[x].time+arr[y].time;
} if(arr[x].num>arr[y].num){
y--;
arr[x].num-=arr[y].num;
}else if(arr[x].num<arr[y].num){
x++;
arr[y].num-=arr[x].num;
}else {
x++;
y--;
}
}
if(arr[x].time+arr[y].time>maxTime){
maxTime=arr[x].time+arr[y].time;
} //3,输出
System.out.println(maxTime);
}
}
/*
M名员工,第i名员工有拖延时间ti
有M/2分工作需要完成,每份工作需要安排2名员工 测试用例1:AC 30%
3
1 8
2 6
1 2 测试用例2:这个第一次没有通过,光标判断不完善导致
4
1 8
1 5
1 2
1 6 测试用例3:测试通过
4
3 8
1 5
1 2
1 6 */

3,两组人员最小差值

  题目: 将一个数组分成两部分,不要求两部分所包含的元素个数相等,要求使得这两个部分的和的差值最小。比如对于数组{1,0,1,7,2,4},可以分成{1,0,1,2,4}和{7},使得这两部分的差值最小。

  这个我当时没有思路【其实有一个遍历的思路,但是他们题目的输入范围大小一看就知道这种方法是不行的】

  思路:差最小就是说两部分的和最接近,而且和所有数的和SUM的一半也是最接近的。假设用sum1表示第一部分的和,sum2表示第二部分的和,SUM表示所有数的和,那么sum1+sum2=SUM。假设sum1<sum2 那么SUM/2-sum1 = sum2-SUM/2; 
  所以我们就有目标了,使得sum1<=SUM/2的条件下尽可能的大。也就是说从n个数中选出某些数,使得这些数的和尽可能的接近或者等于所有数的和的一般。这其实就是简单的背包问题了: 
  背包容量是SUM/2. 每个物体的体积是数的大小,然后尽可能的装满背包。 
  dp方程:f[i][V] = max(f[i-1][V-v[i]]+v[i], f[i-1][V] ) 
  f[i][V]表示用前i个物体装容量为V的背包能够装下的最大值,f[i-1][V-v[i]]+v[i]表示第i个物体装进背包的情况,f[i-1][V]表示第i件物品不装进背包的情况。

  dp动态规划求解,空间复杂度较高,变成了一个背包问题

package com.cnblogs.mufasa.Main3.Demo;

import java.util.Arrays;

public class Dp_backpack {
public static void match(int[] arr){
int sum = Arrays.stream(arr).sum();
int len = arr.length;
int halfOfSum = sum/2; int matrix_firstDimensionLen = len+1;
int matrix_secondDimensionLen = halfOfSum+1;
int[][] matrix = new int[matrix_firstDimensionLen][matrix_secondDimensionLen]; for (int i = 1; i < matrix_firstDimensionLen; i++) {
for (int j = 1; j < matrix_secondDimensionLen; j++) {
//如果第i件物体不装进背包
matrix[i][j] = matrix[i-1][j];
//如果第i件物体装进背包 //备注:j - arr[i-1] >= 0防止下标为负
if(j - arr[i-1] >= 0 && matrix[i - 1][j - arr[i-1]] + arr[i-1] > matrix[i][j]){
matrix[i][j] = matrix[i - 1][j - arr[i-1]] + arr[i-1];
}
}
} System.out.print(matrix[len][halfOfSum]+"\t");
System.out.println(sum-matrix[len][halfOfSum]);
} public static void main(String[] args){
int[] arr = {1,2,3,4,5};
match(arr);
}
}

参考链接:

https://blog.csdn.net/baidu_37107022/article/details/73123817

https://www.cnblogs.com/ranjiewen/p/9085049.html

4,相差输出

  有一组无序的正整数数组,每次输出其最小的正整数,其他所有数字减去这个数,如果所有的数据都为0或者负数,那么直接输出0,这个过程进行k轮

  我的思路是先进行由小到大的排序,之后从头到尾进行逐项判断输出,并且更新当前需要减去的数值大小!,时间复杂度为O(logn+k)

package com.cnblogs.mufasa.Main4;

import java.util.Arrays;
import java.util.Scanner; public class Main {
public static void main(String[] args) {
//0,测试 //1,输入
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int k=sc.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
} //2,处理
Arrays.sort(arr);
int preNum=0;
boolean flag=false;
int loc=0;
for(int i=0;i<k;i++){
if(loc>=n){
System.out.println(0);
}else {
int temp=arr[loc]-preNum;
if(temp<=0){//需要跳到下一个位置
loc=SinNext(arr,preNum,loc+1);
}else {//不小于零
System.out.println(temp);
preNum+=temp;
loc++;
}
} }
//3,输出
} private static int SinNext(int[] arr,int preNum,int loc){//递归调用这里
if(loc>arr.length-1){//直接输出0
System.out.println(0);
return arr.length;
}else {
int temp=arr[loc]-preNum;
if(temp<=0){//需要跳到下一个位置
loc=SinNext(arr,preNum,loc+1);
}else {//不小于零
System.out.println(temp);
preNum+=temp;
loc++;
}
}
return loc;
}
} /*
7 5
5 8 10 3 6 10 8 5 5
1 1 1 1 1 4 5
3 1 3 5
*/

5,异或输出

  有两组正整数数组,他们对方都在各个任取一个相加组成新的数组的内容,例如:

1 2 1 0 0
1 2 3 0 0
你那么新数组就有5*5=25个元素

  将这25个元素全部互相取异或将最后结果输出。这里需要用到数学相关的知识:①异或;②异或;③异或;

  两个相同的数值异或为0;0与任何数值异或为这个数值本身;

例如:

①5^5=0;123^123=0;

②0^1=1;0^15632=15632;

所以我们只要判断出结果中奇数个的数值,将他们异或一次即可得出正确结果;

并且原始两个数组中偶数倍出现的数值可以直接忽略掉,因为偶数倍出现的数值和另外一组数据的任何数值相加也都是相同数值偶数倍出现,那么异或之后必定为0;

关于算法复杂度的问题:其实还好,首先使用的不是穷举法;其次将冗余的一些计算直接掐掉了;算法复杂度大致为O((logn)^2)

package com.cnblogs.mufasa.Main5;

import java.util.*;

public class Main {
public static void main(String[] args) {
//0,测试 //1,输入
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
TreeMap<Integer,Integer> tm1=new TreeMap<>();
TreeMap<Integer,Integer> tm2=new TreeMap<>(); //2,处理
for(int i=0;i<n;i++){
int temp=sc.nextInt();
Object num=tm1.get(temp);
if(num!=null){
tm1.put(temp,((int) num)+1);
}else {
tm1.put(temp,1);
}
} for(int i=0;i<n;i++){
int temp=sc.nextInt();
Object num=tm2.get(temp);
if(num!=null){
tm2.put(temp,((int) num)+1);
}else {
tm2.put(temp,1);
}
} ArrayList<Integer> arrayList1=new ArrayList<>();
ArrayList<Integer> arrayList2=new ArrayList<>(); for(Map.Entry<Integer,Integer> kv:tm1.entrySet()){
if((kv.getValue()^1)==0){
arrayList1.add(kv.getKey());
}
} for(Map.Entry<Integer,Integer> kv:tm2.entrySet()){
if((kv.getValue()^1)==0){
arrayList2.add(kv.getKey());
}
} int temp=0;
for(int i=0;i<arrayList1.size();i++){
for(int j=0;j<arrayList2.size();j++){
temp^=(arrayList1.get(i)+arrayList2.get(j));
}
}
System.out.print(temp); //3,输出 }
}
/*
5
1 2 1 0 0
1 2 3 0 0 2//样例1输出结果 6
4 6 0 0 3 3
0 5 6 5 0 3 8//样例2输出结果
*/

奇妙的算法【10】TX--有效号码、最,小耗时、最小差值、差值输出、异或结果的更多相关文章

  1. 奇妙的算法【11】LeetCode-专属算法面试题汇总

    这个是LeetCode上面的编程训练专项页面,地址:https://leetcode-cn.com/explore/interview/card/top-interview-quesitons-in- ...

  2. php 算法之切割数组,不用array_chunk(),算法之二,取数组的差值,不用array_diff()

    用php写算法切割数组,不用array_chunk();算法例如以下所看到的. <?php //$array 数组 //$size 每一个数组的个数 //每一个数组元素是否默认键值 functi ...

  3. 模板—算法—整体二分(区间k小值)

    模板—算法—整体二分(区间k小值) Code: #include <cstdio> #include <algorithm> using namespace std; #def ...

  4. md5是哈希算法的改进加强,因为不同原始值可能hash结果一样,但md5则改善了用于验证消息完整性,不同md5值原始值也必将不一样

    md5是哈希算法的改进加强,因为不同原始值可能hash结果一样,但md5则改善了用于验证消息完整性,不同md5值原始值也必将不一样

  5. 排序算法(10)--Distribution Sorting--分布排序[2]--Radix Sort--基数排序

    1.基本思想 基数排序是通过“分配”和“收集”过程来实现排序 2.实现原理 基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位.主要分为两个过程: (1)分配,先从个位开 ...

  6. java数据结构和算法10(堆)

    这篇我们说说堆这种数据结构,其实到这里就暂时把java的数据结构告一段落,感觉说的也差不多了,各种常见的数据结构都说到了,其实还有一种数据结构是“图”,然而暂时对图没啥兴趣,等有兴趣的再说:还有排序算 ...

  7. 奇妙的算法【7】-贪婪算法-dp

    问题1描述:[贪婪算法,Dijistra算法] ①有一只兔子要从一个N*N的二维矩阵方格中从上跳到下面: ②每次只能向左或向下,越过一个方格,跳到下一个方格中: ③被越过的方格中的数值,表示该兔子越过 ...

  8. 数据结构和算法 – 10.集合

    集合: 联合.交叉.差异.子集 using System; using System.Collections; using System.Collections.Generic; using Syst ...

  9. 大整数算法[10] Comba乘法(实现)

    ★ 引子 上一篇文章讲了 Comba 乘法的原理,这次来讲讲如何实现.为了方便移植和充分发挥不同平台下的性能,暂时用了三种不同的实现方式: 1.单双精度变量都有的情况. 2.只有单精度变量的情况. 3 ...

随机推荐

  1. 数据库Sequence创建与使用

    最近几天使用Oracle的sequence序列号,发现对如何创建.修改.使用存在很多迷茫点,在上网寻找答案后,根据各路大神的总结,汇总下对自己的学习成果: 在Oracle中sequence就是序号,每 ...

  2. 关于Android studio下V4包 KeyEventCompat 类找不到问题

    V4包 KeyEventCompat 类找不到问题   本文链接:https://blog.csdn.net/shanshan_1117/article/details/84344557 今天我把su ...

  3. 010-多线程-JUC集合-Queue-ConcurrentLinkedQueue

    一.概述 ConcurrentLinkedQueue是线程安全的队列,它适用于“高并发”的场景. 它是一个基于链接节点的无界线程安全队列,按照 FIFO(先进先出)原则对元素进行排序.队列元素中不可以 ...

  4. PAT 甲级 1036 Boys vs Girls (25 分)(简单题)

    1036 Boys vs Girls (25 分)   This time you are asked to tell the difference between the lowest grade ...

  5. beyond compare 4 的试用期过了的处理办法

    beyond compare 是一款好用的对比软件,在广大码农开发过程中,占有很重要的地位,特别是在需要经常合并版本(都是泪) beyond compare 4  30天试用期过期了,在网上找的密钥也 ...

  6. LeetCode_100. Same Tree

    100. Same Tree Easy Given two binary trees, write a function to check if they are the same or not. T ...

  7. DELPHI中 screen.Cursor:=crhourglass; adoQuery.close; adoquery.Open; screen.Cursor:=crdefault;啥意思

    鼠标忙这段代码大概是用来演示鼠标的用法的.具体解释如下: 使鼠标指针为沙漏状.(以表示程序正忙)screen.Cursor:=crhourglass; 把(打开的)数据库关闭.adoQuery.clo ...

  8. 使用 Sublime + PlantUML 高效地画图

    转自 http://www.jianshu.com/p/e92a52770832

  9. iOS-UIScrollView滚动视图(转)

    http://blog.csdn.net/iukey/article/details/7319314 UIScrollView 类负责所有基于 UIKit 的滚动操作. 一.创建 CGRect bou ...

  10. iOS-objective-c产生随机数的方法

    objective-c 中三种产生随机数的方法 //arc4random() 比较精确不需要生成随即种子 //通过arc4random() 获取0到x-1之间的整数的代码如下:     int val ...