十道算法题[二]上

简介: 笔记

前言


清明不小心就拖了两天没更了~~

这是十道算法题的第二篇了~上一篇回顾:十道简单算法题

最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下,重温一下。

只能说慢慢积累吧~下面的题目难度都是简单的,算法的大佬可直接忽略这篇文章了~入门或者算法薄弱的同学可参考一下~

很多与排序相关的小算法(合并数组、获取数字每位值的和),我都没有写下来了,因为只要会了归并排序(合并数组),会了桶排序(获取数字每位的值),这些都不成问题了。如果还不太熟悉八大基础排序的同学可看:【八大基础排序总结】

由于篇幅问题,每篇写十道吧~

如果有错的地方,或者有更好的实现,更恰当的理解方式希望大家不吝在评论区留言哦~大家多多交流


十道简单算法题


题目的总览


  1. 删除下标为k的元素
  2. 找出常用的数字
  3. 丢失的数字
  4. 将0放在数组最后
  5. 找出数组的单个数字
  6. 画三角形星星
  7. 罗马数字倒转成阿拉伯数字
  8. 啤酒与饮料
  9. 简单凯撒密码
  10. 求最大公约数


一、删除下标为k的元素


删除下标为k的元素

思路:数组后一位往前覆盖即可~

/**
     * 删除下标为k的元素
     */
    public static void deleteK() {
        //固定的常量(比数组元素的个数要大)
        int N = 10;
        int[] arrays = new int[N];
        //对数组进行初始化
        for (int i = 0; i < 8; i++) {
            arrays[i] = i;
        }
        //要删除下标
        int k = 7;
        for (int i = k; i < N - 1; i++) {
            arrays[i] = arrays[i + 1];
        }
        System.out.println("公众号:Java3y" + arrays);
    }


二、找出常用的数字


给你一个长度为n的数组,其中有一个数字出现的次数至少为n/2,找出这个数字

这道题可以用栈的思想来做:

  • 如果栈是空的,那么先把数据存进去
  • 然后继续遍历其他的数据,只要发现栈中的数据和遍历中的数据不一样,那么就出栈
  • 如果是相同的,那么就入栈
  • 其实就是捉住数字出现的次数多于数组一半的长度这里入手。如果这个数出现的次数是大于这个数组长度的2/1,那么最后留下的肯定是这个数

80.jpg

/**
     * 找出常用的数字:
     * 给你一个长度为n的数组,其中有一个数字出现的次数至少为n/2,找出这个数字
     */
    public static void findMajorityElement(int[] arrays) {
        //构建一个静态栈
        int[] stack = new int[arrays.length];
        // 栈的front指针
        int front = -1;
        // 遍历给出的数组
        for (int i = 0; i < arrays.length; i++) {
            // 判断该栈为空,那么直接将元素入栈
            if (front == -1) {
                stack[++front] = arrays[i];
            } else if (stack[front] == arrays[i]) { // 该元素是否与栈的元素一致-->继续入栈
                stack[++front] = arrays[i];
            } else {
                // 只要不一致,就出栈
                front--;
            }
        }
        // 只要该数字出现次数大于数组长度的2/1,那么留下来的数字肯定在栈顶中
        System.out.println("关注公众号:Java3y--->" + stack[0]);
    }

优化:

  • 其实没必要用整个栈来装载数组,因为我们就使用栈顶元素(出现次数最多的那个),而栈的大小也可以通过一个变量就可以来确定了
  • 只要元素相同->入栈(长度+1)。元素不相同-->出栈(长度-1)
  • 最终留下来的肯定是出现最频繁的那个数字!
public static void findMajorityElement2(int[] arrays) {
        // 装载栈的元素
        int candidate = -1;
        // 栈的大小(长度)
        int count = 0;
        // 遍历给出的数组
        for (int i = 0; i < arrays.length; i++) {
            // 判断该栈为空,那么直接将元素入栈
            if (count == 0) {
                candidate = arrays[i];
                count++;
            } else if (candidate == arrays[i]) { // 该元素是否与栈的元素一致-->入栈(栈多一个元素)
                count++;
            } else {
                // 只要不一致-->出栈(栈少一个元素)
                count--;
            }
        }
        // 只要该数字出现次数大于数组长度的2/1,那么留下来的数字肯定在栈顶中
        System.out.println("关注公众号:Java3y--->" + candidate);
    }


三、丢失的数字


给你一个数组{0,1,2,3,….n},其中有一个数字缺失,请把缺失的数字找出来

思路:

  • 创建一个数组(题目数组的长度+1,因为题目的数组缺失了一个)
  • 创建的数组元素用特殊的符号(数字)来进行填满
  • 将题目给出的数组遍历并填充到创建的数组上,用index(0,1,2,3..)替代
  • 最后遍历创建的数组,哪个还是特殊的符号就是缺失的数字,返回index(缺失的数字)即可
/**
     * 找到缺失的数字
     *
     * @param arrays
     */
    public static void missingNumber(int[] arrays) {
        // 定义要填充到新数组的数字(随意)
        int randomNumber = 89898980;
        // 创建一个新的数组(比已缺失的数组多一个长度)
        int[] newArrays = new int[arrays.length + 1];
        // 填充特殊的数字进新数组中
        for (int i = 0; i < newArrays.length; i++) {
            // 随意填充数组到新数组中
            newArrays[i] = randomNumber;
        }
        // 遍历题目的数组并使用index替代掉新数组的元素
        for (int i = 0; i < arrays.length; i++) {
            // 题目数组的值[0,1,2,3,4,...n]其中有一个缺失
            int index = arrays[i];
            // 重新填充到新数组上,index对应着题目数组的值
            newArrays[index] = 3333333;
        }
        // 遍历新数组,只要还有值为89898980,那么那个就是缺失的数字
        for (int i = 0; i < newArrays.length; i++) {
            if (newArrays[i] == randomNumber) {
                System.out.println("关注公众号:Java3y---->缺失的数字是:" + i);
            }
        }
    }

结果:

81.jpg

优化:

  • 题目给出的数组{0,1,2,3,4,5,....n}其中缺失一个数字,要把缺失的数字找出来…我们可以回顾一下高中学过的等差求和公式:Sn=(a1+an)n/2
  • 82.png
  • 假设我们没有缺失数字,等差求和公式可以快速得出答案。比如:{0,1,2,3}--->(0+3)*4/2--->6,如果此时缺失的是2呢,就是说题目的给出的数组是:{0,1,3},我们利用等差公式求和之后减去数组每个元素,最后剩下的数就是缺失的数字!6-1-3-0--->2

所以,我们可以写出这样的代码:

/**
     * 利用等差公式找到缺失的数字
     *
     * @param arrays
     */
    public static void missingNumber2(int[] arrays) {
        // 套用等差求和公式
        int sum = (arrays[0] + arrays[arrays.length - 1]) * (arrays.length + 1) / 2;
        // 遍历数组,得出的sum减去数组每一位元素,最后即是缺失的数字
        for (int value : arrays) {
            sum = sum - value;
        }
        System.out.println("关注公众号:Java3y---->缺失的数字是:" + sum);
    }

结果:

83.jpg


四、将0放在数组最后


将一个数组的元素,其中是0的,放在数组的最后

思路:

  • 使用一个变量zero来记住该数组有多少个0
  • 遍历这个数组,如果发现不是0的,就往数组前面移动,如果发现是0就zero++
  • 数组移动的位置刚好是arr[i-zero]

代码实现:

/**
     * 移动元素0到数组最后
     *
     * @param arrays
     */
    public static void moveZero(int[] arrays) {
        // 记录该数组有多少个0元素
        int zero = 0;
        for (int i = 0; i < arrays.length; i++) {
            // 只要元素不为0,那么就往前面移动
            if (arrays[i] != 0) {
                arrays[i - zero] = arrays[i];
            } else {
                // 如果为0,那么zero ++
                zero++;
            }
        }
        // 1. 前面已经将非0的元素移动到数组的前面了
        // 2. 将为0的元素填满数组,填充的位置就从length - zero开始
        int j = arrays.length - zero;
        while (j < arrays.length) {
            arrays[j] = 0;
            j++;
        }
        System.out.println("关注公众号:Java3y---->" + arrays);
    }

结果:

84.jpg

还可以换种思路(差别不大):将数组分成几个部分:在j之前的没有0,j到i全是0,i后面还没有遍历

  • 如果遍历到的数字不是0,那么跟j进行交换,j++(保证j前面没有0和j到i全是0)
  • 直至i遍历完毕后,j前面都不是0,j-i都是0(这就完成我们的任务了)

代码实现:

/**
     * 移动元素0到数组最后
     *
     * @param arrays
     */
    public static void moveZero2(int[] arrays) {
        // 在j前面的元素都不是0
        int j = 0;
        for (int i = 0; i < arrays.length; i++) {
            if (arrays[i] != 0) {
                // 跟j进行交换,保证j的前面都不是0
                int temp = arrays[i];
                arrays[i] = arrays[j];
                arrays[j]  = temp;
                j++;
            }
        }
        // 直至i遍历完毕后,j前面都不是0,j-i都是0(这就完成我们的任务了)
        System.out.println("关注公众号:Java3y---->" + arrays);
    }

结果还是一样的:

85.jpg

目录
相关文章
|
机器学习/深度学习 存储 人工智能
【c++百日刷题计划】 ———— DAY4,带你轻松学习算法
【c++百日刷题计划】 ———— DAY4,带你轻松学习算法
148 0
|
机器学习/深度学习 算法 C++
【c++百日刷题计划】 ———— DAY6,带你轻松学习算法
【c++百日刷题计划】 ———— DAY6,带你轻松学习算法
171 0
|
存储 算法 C++
【c++百日刷题计划】 ———— DAY7,带你轻松学习算法
【c++百日刷题计划】 ———— DAY7,带你轻松学习算法
171 0
|
机器学习/深度学习 移动开发 算法
【c++百日刷题计划】 ———— DAY5,带你轻松学习算法
【c++百日刷题计划】 ———— DAY5,带你轻松学习算法
192 0
|
机器学习/深度学习 算法 程序员
初入算法(2)—— 进入算法世界
本章将会继续在初入算法(1)——进入算法世界 的基础上继续通过趣学算法进行算法的学习。
159 1
初入算法(2)—— 进入算法世界
|
存储 自然语言处理 算法
初入算法(1)—— 进入算法世界
了解算法,学习算法,应用算法
143 0
初入算法(1)—— 进入算法世界
|
算法 Java
洛谷新手村算法题分析
本文汇总洛谷新手村算法题的分析解答,题目代码基本由Java实现。
115 0
洛谷新手村算法题分析
|
算法 NoSQL 数据挖掘
工程师应该学点算法——图论2
工程师应该学点算法——图论2
工程师应该学点算法——图论2
下一篇
无影云桌面