算法小结-自用

6.28

一.最大字母出现次数

1.哈希表的使用

#include< unordered_map>

建立:unordered_map<char, int> Hash;//建立一个键为char,值为int的Hash表

初始化:Hash.insert(make_pair((char)i, 0));//插入数据,其中make_pair()意思是让后边的数据作为一个整体。

遍历:

for (auto h : Hash) { char c = h.first;//first代表哈希表的键 int n = h.second;//second代表哈希表的值 }`

查找:Hash.find(“需要查找的键”)如果需要返回是否得到结果,则加上:

if (Hash.find(s.at(i)) != Hash.end())//找到了数据

第二种查找方法:

Hash.count('a')//若Hash表中含有a则返回1否则返回0

赋值:Hash[“键的名字”]="赋给它的值"

其他函数:

m.size() //返回哈希表的大小

m.empty() //判断哈希表是否为空,返回值为true/false

m.clear() //清空哈希表

二.输出成绩

1.动态创建数组

int *grade=new int[n];//其中n可以后边输入或者定义

使用完数组之后记得清除空间

delete []grade;

2.需要整数相除得到小数时需要类型向上转

double = int 再用 double 相除

结果设置精度:

#include <iomanip>

<<setprecision(2)<<"输出的数据"

三.千年难遇的日子

1.int转字符串 to_string

string s=to_string("int a");

2.字符串常用函数

`string.find("输入要查找的字符串,如果有则返回出现的下标否则-1") string.insert("向指定位置插入字符串")

string.substr(”截取字符串 start 起点(包含),num 字符个数)//若仅一个参数i 则代表从该倒数i第一直到结尾的字符串

string.replace(“替换字符串)

string.at('获取目标字符的下标,没有则返回-1')

string rs = s.substr(4, 4);
    rs.reserve();//reverse没有返回值 直接对原字符串进行操作

6.29

一.门牌制作

1.提取数字中各位想要的数字(eg 提取数字2)

(1)字符串提取:

s=to_string(int);
char aim='目标字符';

for (int i = 0; i < s.length(); i++)

{

if (s.at(i) == aim)count++;

}

(2)逻辑运算:

int num = 0;
    for (int i = 1; i <= 2020; i++) {
        if (i % 10 == 2) num++;//提取个位
        if (i / 10 % 10 == 2) num++;//提取十位
        if (i / 100 % 10 == 2) num++;//提取百位
        if (i / 1000 == 2) num++;//提取千位
    }

二.卡牌排序

1.char 转int(数字转换 不是ASSCII码)

string s="10086"; 0<=i<=s.length()

int index = s.at(i)-'0';

2.String 转 int

string a = "123";
int num = atoi(a.c_str());

三.🗡☞Offer字符串

字符串函数概述:

1.将字符串str中的空格换成%20

(1)使用string的replace函数 第一个参数为替换的位置 第二个参数为替换的部分长度 第三个参数为替换的字符串

for (int i = 0; i < str.length(); i++)
    {
        char aim = ' ';
        string result = "%20";
        if (str.at(i) == aim)
            str.replace(i,1,result);
    }
    return str;
    }

(2)不使用函数

原理:由于c++中string 对象是可以修改的,所以先找到所有空格的位置然后将需要的字符串添加进去。

2.左旋字符串若干位到右边

(1)使用库函数 略,直接substr()截取再append()就完事了

(2) 使用翻转的思想,来自句子翻转单词灵感 :

this is  a new stage->egats wen a si siht

再将每一个单词翻转:

stage new a is this 

就完成了句子单词的翻转。

同理对于一个字符串也可以:

    string s2="需要转换得到字符串"
    reverse(s2.begin(),s2.end() );//第一步反转 所有字符
    reverse(s2.begin(), s2.end() - n);//反转
    reverse(s2.end() - n, s2.end());
    cout << s2;

对于reveres的使用,需要传入字符串的起止位置与结束位置即可。

  //char 转 string:
  string s;
  char a='a';
  s.append(1,a);

8.11

一.IP换算

输入字符串判别是非为IPv6或者IPv4,若均不是则返回Neither

IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1; 同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。

IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。

(1).判别split后是否存在,看返回值 若为-1则表示不存在

(2).判别字符串是否为数字

               char c = s[i].charAt(j);
                if (c < '0' || c > '9')
                    return false;

(3).字符转数字

num = num * 10 + (int)(c - '0'); 

(4).判别是否为字母

  boolean expr = ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ;

(5).进行字符串分割时 "."不能直接写 要进行转义 "\." 不要写反了

    String test1="256.256.256.256";
        String[] split = test1.split("\\.");

(6)天坑题 1:2:3:4:5:6:7:8: 最后多了个:为无效 要考虑进去

尤其是分割类的题目 按照特定条件进行分割,出现边界要进行判断,非法字符串但能的到合法结果

二.告警抑制__遍历Hashmap以及remove注意事项

(1)注 : 我们不能在遍历Map时使用map.remove()方法 , 否则就会抛出异常 :

可以使用迭代器进行删除 iteRator.remove();

(2)hashmap使用

创建:HashMap map=new HashMap<>();

插入键值:map.put(key,value);

获取:

map.get(key);

判别是否含有键:

boolean b=map.containsKey(key)

遍历:

 Set set = map1.entrySet();
    Iterator iter = set.iterator();
    while (iter.hasNext())
    {
        Map.Entry entry=(Map.Entry) iter.next();
        Object key=entry.getKey(); //获取键
        Object value=entry.getValue();//获取值
        
      }

删除:

map.remove(key)

排序:

更新:

map.put(key,newVal)

三.排序

1.身高排序2550__自定义比较器

对类中的某一项进行排序

自定义分类器:

**注意:自定义Hash表的比较器(==分类器)时

输入的顺序与看到的顺序不是一致的当比较的值一样时候(由于是链式存储)

比如:abc 13 bca 13 djk 13

若按照值排序 且相等返回0 应该是原来的顺序

但是 链式存储 输入后的顺序被打乱了 “原来的顺序也就是乱的”

但是不相等的情况 升降排序还是没有问题 或者相等时指定键的位置也可以避免这种情况

class AgeComparator implements Comparator<Person> {
    public int compare(Person object1, Person object2) {// 实现接口中的方法
        //return new Integer(object1.getHeigh()).compareTo(object2.getHeigh()); 
        //上诉是:若只需要按照某一项进行排序eg height
        
          if (object1.heigh== object2.heigh)
              return new Integer(object1.getWeight()).compareTo(object2.getWeight());
        else
          return new Integer(object1.getHeigh()).compareTo(object2.getHeigh());
//注意 compareTo方法 是返回一个值 大于0表示前者大于后者(降序排列) 小于1是后者大于前者(升序排列) (注意相等的情况)
        //return 0时 不对原来的集合对应元素做处理
    }
}
ArrayList<Person> people=new ArrayList<>();//创建集合然后将类对象装入集合中去 再调用Collections.sort 即可
       AgeComparator comparator=new AgeComparator();//比较器
        Collections.sort(people,comparator);//集合调用
        for (Person p:people//查看结果
             ) {
            System.out.println(p.lable);
        }
class comparePeople implements Comparator<people>//比较器 降序排列时
{
    public int compare(people p1,people p2)
{
    if (p1.height==p2.height)
    {
        // return new Integer (p1.wight).compareTo(p2.wight);
        return  p1.wight>=p2.wight?-1:1;
    }
        else
    //return new Integer (p1.height).compareTo(p2.height);
    return  p1.height>p2.height?-1:1;
​
}
2.拔河__控制输入
while (scanner.hasNextLine())
{
    String s1=scanner.nextLine();
    if (s1.equals(""))//输入任意行 当输入为空行时结束
        break;
    final String[] s2 = s1.split(" ");
    int height=Integer.valueOf(s2[0]);
    int weight=Integer.valueOf(s2[1]);
    list.add(new people(height,weight));
​
}
3.根据哈希表的值进行排序/键进行排序 以及entry的使用
//自定义比较器
class compareDesk implements Comparator<Map.Entry<String,Integer>> //对键值对进行排序设定 按照值还是键可以自定义
{
   public int compare(Map.Entry<String,Integer> entry1, Map.Entry<String,Integer> entry2)
   {
         return new Integer (entry1.getValue().compareTo (entry2.getValue()));//按照值进行排序
     //  return new Integer (entry1.getKey().compareTo (entry2.getKey()));按照键进行排序
   }
   
}
 
//使用哈希map的情况 先将Hashmap转换成Entry集合 然后将集合转为list再传入collection进行sort排序
      HashMap<String,Integer> mapp=new HashMap<>();
//初始化 HashMap 略去
        Set<Map.Entry<String, Integer>> entries = mapp.entrySet();
        List<Map.Entry<String, Integer>>list1=new LinkedList<>(entries);
        Collections.sort(list1,new compareDesk());
//直接使用Entry的情况 list直接add
​
 ArrayList<Map.Entry<String,Integer>> list=new ArrayList<>();//Entry 集合
              Map.Entry<String,Integer> map=new AbstractMap.SimpleEntry<>(temp,store);//初始化一个Entry
              list.add(map);
        Collections.sort(list,new compareDesk());
        for (Map.Entry<String,Integer> a:list
             ) {
            System.out.println(a.getKey());
        }
Array 进行自定义数组排序 也可以是二维数组 注意Integer不是int 以及重写compare可以写在方法里面new 里面
        Integer []arr={23,23,4,1,5};
        Arrays.sort(arr,new Comparator <Integer>(){
            public int compare(Integer a,Integer b)
            {
                return a>=b?-1:1;//降序
                return a>b?1:-1;//升序
            }
        });
4.括号检查__栈的应用 *

匹配括号可以借用 hash表

认真读题,先思考好问题的关键,比如嵌套的判定

写好注释

5.篮球比赛

题目完善——当输入需要上次记录但是没有时 直接输出-1;

统计数组 更简洁

  while (!stack.isEmpty()){
            sum += stack.pop(); 
6.仿lisp计算

在题目的例子下 自己再给出两三个测试案例

split方法只能去除一个空格,而不能去除多个空格 但可以使用split然后再将分出的数组中为 空的进行改变->error进行标识

遍历后排除error 使用

7.找车位 *注意距离而不是空位数

事先举出所有的例子,包括所有特殊情况

逻辑清楚 返回两个最大-> 二元表达式 或者math.max(int a,int b);

     maxDistence = maxDistence > ((i- lastCar) / 2) ?maxDistence : ((i - lastCar) / 2);
                        
       //或者         maxDistence=Math.max(maxDistence,(i-lastCar)/2);
8.找和的绝对值最小的两个数 *非要从大到小排序(之和一样情况下 去绝对值大的两个数)
 if (Math.abs(input[i]+input[j])==min) //相等时的情况 11 -11 222 -222 取后者
                {
                    if (Math.abs(input[i])+Math.abs(input[j])>Math.abs(one)+Math.abs(two))
                    {
                        one=Math.min(input[i],input[j]);
                        two=Math.max(input[i],input[j]);
                    }
                }
9.求有效子字符串 *子串必须 含有两个连续字母??

复习:求一个字符串的子串

所有子串:利用00000-11111特性

eg:1abcde

连续子串:双指针加substring

eg:1abcde

    public static void founction2(String input,int n)
    {
        for (int i = 0; i < n; i++) {
            for (int j = i+1; j < n+1; j++) {
                System.out.println(input.substring(i,j));
            }
        }
    }
10.位运算

eg :abc

数字    二进制    子串
0       000      ""
1       001      "c"
2       010      "b"
3       011      "bc"

一定要注意题目中非法的情况 一定要注意题目中非法的情况 一定要注意题目中非法的情况

有限处理非法情况 eg 返回-1等

11.输入变换函数 Arrays.mapToInt
         String caces[]={"2","32","4"};
         int[] ints = Arrays.stream(caces).mapToInt(Integer::parseInt).toArray();
         //可用于 划分为数字的字符串数组
         6
         15
         3 4 5 7 9 10    23/5==5
12.食堂供餐* 解决问题方法:1. 直接法:直接找到(算出)目标 2.穷举法或逼近法 间接得到答案

先找到最小的出餐速度,然后看每小时吃的人够不够,不够直接出餐速度加1

然后再次遍历每小时的人数

13.开放日活动 逆天 注意查看 要求输出有没有空格 //90分

数组统一填充:

int put[]=new int [6];
Arrays.fill(put,6);
12 .消消乐 读取矩阵 DFS
Scanner scanner=new Scanner(System.in);
        int matrixRows= scanner.nextInt();
        int matrixCols= scanner.nextInt();
        int matrix[][]=new int[matrixRows][matrixCols];
        for (int i = 0; i < matrixRows; i++) {
            for (int j = 0; j < matrixCols; j++) {
                      matrix[i][j]= scanner.nextInt();
            }
        }
 boolean b[][]=new boolean[2][2]; 默认全是false
方向数组与xy轴上有区别
数学上:x,y->x+1,y
数组上:x,y->x,y+1
int [][]nextDirections={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};//八个方向上检测
13.广播服务器
DFS 的套路
关键 设置边界条件
优化 设置已经访问过的路
必要 方向数组,然后遍历
控制输入  错误做法
        while (scanner.hasNextLine())
        {
            if (scanner.nextLine().equals(" "))//错误 应该是""null 而不是" "空
                break;
            list.add(scanner.nextLine());//错误 应该使用一个String 暂存 而不是再次调用scanner.nextLine
正确做法
        while (scanner.hasNextLine())
        {
            String temp=scanner.nextLine();
            if (temp.equals(""))
                break;
            list.add(temp);
        }
6 1
3 15 ()
1 20 (2)
2 10 (3,4)
4 23 (5,6,7)
6 10 ()
7 10 ()
14.文件目录大小
 Arrays.stream(split).mapToInt(Integer::parseInt).toArray();如何处理有空白的情况
     //先把”“ 去掉 记得使用equals 而不是==
     if (split.length>=1&&!split[0].equals("")) {
                int[] sonFiles = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
                map.put(fileCode, new file(fileSize, sonFiles));
            }
15.挖矿 作用域问题 方法可以修改数组但是不能修改变量 除非是全局变量
        int c=10;
        f1(c);
        System.out.println(c);
    public static void f1(int count)
    {
        count=count+10;
    }
输出结果是10 而不是20
     public void f1(int x)
    {
        x=x+1;
    }
    public void f2(int x[])
    {
        x[0]=1;
        x[1]=0;
    }
f1 对x的修改无效 f2对x的修改有效
    复制粘贴时注意所有参数需要改变的地方一定要修改
    
    5 5
    1  2   3  5  7
    9  14  16 15 18
    8  10  8  7  8
    11 14  8  9  10
    3  5   7  7  4
    
16.机器人走格子 审题 *机器人可以从任何地方开始走
17.linux 发行版关联数量
18.模拟—密码字符串替换 动态修改字符串 拼接技术

sb题

19.BFS算法

队列的使用 没有专门的Queue 可以使用Linkedlist

public class Queue_Exercise {
	public static void main(String args[]) {
		// 创造一个实例对象
		Queue<Integer> queue = new LinkedList<>();
		// 入队操作(尾插法) offer() 添加元素
		queue.offer(1);
		queue.offer(2);
		queue.offer(3);	
		// 出队操作 poll() 返回队首元素并删除
		queue.poll();
		queue.poll();
		// 输出队首元素 peek() 返回队首元素不删除
		System.out.println(queue.peek());
		//判断队列是否为空  isEmpty()
		System.out.println(queue.isEmpty());
	}
}
20 DP问题 打家劫舍
填充任意数组为0 初始化后不设置值 则默认为0
    左闭右开
      int array[]={2,3,4,6,4,3};
         int a2[]=Arrays.copyOfRange(array,0,3);
         int a3[]=Arrays.copyOfRange(array,1,4);
//a2->2 3 4
//a3->3 4 6
21.火星改造 BFS多源问题 与LeeCode 994. 腐烂的橘子 类似

YES YES NO NA NO NO NO NO NA NA YES NO NO NO YES

重大失误 第二次

BFS与DFS中 for 循环 中的变量不要再外边int 不然循环中会出现累加效应

int x=needCope.peek().x;
int y=needCope.peek().y;
 for (int next[]:Directions //错误 每次会进行累加 导致结果错误
                     ) {
                   int x=x+next[0];
                    int y=y+next[1];
}
for (int next[]:Directions //正确
                     ) {
                   int x=needCope.peek().x+next[0];
                    int y=needCope.peek().y+next[1];
}
22.网络信号衰减
//新建数组
new int[]{2,6}

一维延伸成二维数组

//0 0 0 -1 0 0 0 0 0 0 0 0 -1 4 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 
//matrix[6][5]二维  split2[]一维
 for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                matrix[i][j]=split2[i*cols+j];//6 5
            }
        }

5 720 120

840 120

320 100

320 89

777 100

23.种树 从某个区间中找到某一个值 可以考虑二分查找 然后加上一个判断函数
24.下棋 关于离中间近的判断 cao 6子棋特殊情况
25.回文子串

StringBuffer并没有重写equals方法!!!

  • 38
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值