`

大公司面试算法题 - 第一题

阅读更多
最近电话面了个大公司,具体就不说是哪儿啦,电话面试了大概一个小时,都是算法题,面得不太好,主要是电话面,没有用笔什么的。每道题不记效率都可以给个解答方案,但人家要求时间复杂度比较高。我在对方提示下可以把大方面说出来。估计去这个公司复面是没戏了。

回去后把第一题题做出来了。下面是题目:





题目描述

给定一个整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = 2 + 1, 4 = 1 + 3。




下面是我的代码

Base.java -- 这个类只是为了打日志用的





public class Base
{
    public static int debug = 1;

    public void setDebug(int debugLevel)
    {
        Base.debug = debugLevel;
    }

    public static void debug(String str)
    {
        if (1 >= debug)
            System.out.println(str);
    }

    public static void info(String str)
    {
        if (2 >= debug)
            System.out.println(str);
    }

    public static void warn(String str)
    {
        if (3 >= debug)
            System.out.println(str);
    }

    public static void error(String str)
    {
        if (4 >= debug)
            System.out.println(str);
    }
}




下面是解题的类。实现了两种算法,然后在MAIN中对它们的运行时间进行了比较。第一种时间复杂度是O(n^3),第二种是O(n^2),大家看一看吧。




import java.util.Arrays;
import java.util.Random;

/**
* <pre>
* <b>描述</b>
* 给定一个整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列1 2 3 4,
* 这个问题的答案就是2, 因为3 = 2 + 1, 4 = 1 + 3。
* <b>输入</b>
* 第一行是一个整数T,表示一共有多少组数据。 1&lt;= T &lt;= 100
* 接下来的每组数据共两行,第一行是数列中数的个数n ( 1 &lt;= n &lt;= 100),第二行是由n个整数组成的数列。
*
* <b>输出</b>
* 对于每组数据,输出一个整数(占一行),就是数列中等于其他两个数之和的数的个数。
* 样例输入
* 2
* 4
* 1 2 3 4
* 5
* 3 5 7 9 10
* 样例输出
* 2
* 1
* </pre>
*
* @author zy
*/
public class HowManyNumIsOthersSum extends Base
{
    static Random random = new Random();

    public static void main(String[] args)
    {
        int max = 10000;
        int length = random.nextInt(max / 2);
        int[] is = new int[length];
        for (int i = 0; i < is.length; i++)
            is[i] = random.nextInt(max);
        HowManyNumIsOthersSum test = new HowManyNumIsOthersSum();
        test.setDebug(1);
        Arrays.sort(is);
        // 先把此序列排序

        info(Arrays.toString(is));
        long start;
        long end;

        start = System.currentTimeMillis();
        test.calc(is);
        end = System.currentTimeMillis();
        info("calc() used " + (end - start) + "ms");

        start = System.currentTimeMillis();
        test.calc2(is);
        end = System.currentTimeMillis();
        info("calc2() used " + (end - start) + "ms");
    }

    public int calc(int[] array)
    {
        // 记录有多少个这样的数

        int total = 0;
        // 然后从第三个开始算起

        for (int i = 2; i < array.length; i++)
        {
            if (isSum(array, i))
                total++;
        }
        info("此数组共有 " + array.length + " 个元素, 共有 " + total + " 组数据满足要求");
        return total;
    }

    /**
     * 第一种算法,全扫描,把每个比它小的两个数相加所是否与其相等
     *
     * @param array
     * @param target
     * 目标数位置
     * @return
     */
    private boolean isSum(int[] array, int target)
    {
        for (int i = 0; i < target - 1; i++)
        {
            for (int j = i + 1; j < target; j++)
            {
                int result = array[i] + array[j];
                if (result == array[target])
                {
                    debug(target + " array[" + i + "] + array[" + j + "] = array[" + target + "] " + array[i]
                            + " + " + array[j] + " = " + array[target]);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 第二种算法
     *
     * @param array
     */
    public int calc2(int[] array)
    {
        // 记录有多少个这样的数

        int total = 0;
        // 然后从第三个开始算起

        for (int i = 2; i < array.length; i++)
        {
            if (quickIsSum(array, i))
                total++;
        }
        info("此数组共有 " + array.length + " 个元素, 共有 " + total + " 组数据满足要求");
        return total;
    }

    /**
     * 此数是否是
     *
     * @param array
     * 数组
     * @param target
     * 目标数位置
     * @return
     */
    private boolean quickIsSum(int[] array, int target)
    {
        int t = array[target];
        int left = 0;
        int right = target - 1;
        while (left < right)
        {
            int sum = array[left] + array[right];
            if (sum == t)
            {
                debug(target + " array[" + left + "] + array[" + right + "] = array[" + target + "] "
                        + array[left] + " + " + array[right] + " = " + t);
                return true;
            }
            else if (sum < array[target]) // 和小于目标

            {
                left++;
            }
            else // 和大于目标

            {
                if (array[left] + array[left] > t)
                {
                    return false;
                }
                right--;
            }
        }
        return false;
    }
}

分享到:
评论

相关推荐

    算法大全-面试题-数据结构

    第一种算法使用迭代的方式,通过额外的变量存储当前节点的下一个节点和再下一个节点,逐步调整指针,实现整个链表的反转。第二种算法则采用了递归的方式,通过递归函数调用自己来完成链表的反转。两种方法都需要注意...

    算法大全-面试题-数据结构.docx

    - **找倒数第k个元素**:可以使用双指针,一个指针先向前移动k步,然后两个指针同时移动,当先移动的指针到达末尾时,另一个指针即指向倒数第k个元素。 - **找中间元素**:快慢指针法,快指针每次移动两步,慢指针...

    华为od的面试算法真题

    - **游戏目标**:第一个报出数字7的玩家获胜。 - **任务**:当起始数字为M(10≤M≤10000)时,计算在B赢得比赛的所有可能组合的总数。 #### 解题思路分析 本题的核心在于利用动态规划方法,通过构建状态转移方程来...

    面试算法必刷题-算法复习.pdf

    本文件中提到的“面试算法必刷题-算法复习.pdf”强调了几个关键的数据结构和算法知识点,下面我将详细解释这些内容。 首先,数组和链表是数据结构存储方式的两种基本形态。数组是顺序存储的结构,其优点在于可以...

    JAVA经典算法面试39题及答案

    JAVA经典算法面试39题及答案 本资源总结了39道经典的 JAVA 算法面试题目,每个题目都附带答案,涵盖了常见的算法问题,旨在帮助读者更好地掌握 JAVA 编程语言和算法设计。 算法概述 算法是计算机科学中最重要的...

    算法大全-面试题-链表-栈-二叉树-数据结构

    这通常通过两次遍历来完成:第一次遍历获取链表长度,第二次遍历至特定位置(长度减去3)。更高效的方法是使用双指针技术,其中一个指针先向前移动三步,然后两个指针同步移动,当先移动的指针到达链表尾部时,另一...

    算法大全-面试题-数据结构1

    【算法大全-面试题-数据结构1】这篇文章主要探讨了单链表的相关操作,这些操作在面试中常常作为考察点,对于理解数据结构和算法至关重要。以下是对文章中提到的知识点的详细说明: 1. **单链表反转**:单链表反转是...

    面试高频算法题总结-剑指Offer题解

    面试高频算法题总结-剑指Offer题解,主要包含: 数据结构 数组 字符串 链表 栈和队列 二叉树 图 堆 线段树 字典树 单调栈 算法 二分查找 排序 递归 动态规划 分治 记忆化搜索 贪心 回溯 位运算 数学 设计 其他 共66...

    [最新答案V0.4版]微软等数据结构+算法面试100题[第41-60题答案]

    微软等公司数据结构+算法面试100题之...1.[最新整理公布][汇总II]微软等数据结构+算法面试100题[第1-80题] http://download.csdn.net/source/28460552 [第一部分]精选微软等公司数据结构+算法经典面试100题[1-40题] ...

    Android面试算法题

    ### Android面试算法题知识点解析 #### 一、基础算法题:找出未放入数组中的两个数 **题目背景:** 在Android开发过程中,处理数组是非常常见的需求之一。此题旨在考察应聘者对基本数据结构(如数组)的理解以及...

    算法面试经典 100题

    1. **双指针法**:使用两个指针,一个从第一个链表开始,另一个从第二个链表开始。 2. **同步移动**:当一个指针到达链表末尾时,将其移动到另一个链表的头部继续遍历。 **实现细节**: - 定义两个指针`p1`和`p2`,...

    算法大全-面试题-链表-栈-二叉树-数据结构.docx

    以上就是针对链表、栈、二叉树以及数据结构的一些常见面试题及其解题思路。这些知识点在实际的软件开发和算法设计中都有着广泛的应用。掌握这些基本操作和算法,对于提升编程能力和解决复杂问题的能力至关重要。

    微软等公司数据结构+算法面试第1-100题汇总(21题-40题答案)

    ### 数据结构与算法面试知识点(21题-40题) #### 第21题:整数求和的所有可能组合 **题目描述**:输入两个整数`n`和`m`,从数列1,2,3,...,n中随意取几个数,使其和等于`m`,要求将其中所有的可能组合列出来。 ...

    微软等公司数据结构_算法面试第1-100题汇总.pdf

    从给定的文件信息中,我们可以总结出一系列与数据结构和算法相关...以上题目不仅涵盖了数据结构的基本操作,还深入到了算法设计和优化,对于准备IT行业面试,尤其是针对微软等大公司的求职者而言,具有较高的参考价值。

Global site tag (gtag.js) - Google Analytics