连续数组的最大和

 

牛牛得到一个长度为n的整数序列V,牛牛定义一段连续子序列的幸运值为这段子序列中最大值和次大值的异或值(次大值是严格的次大)。牛牛现在需要求出序列V的所有连续子序列中幸运值最大是多少。请你帮帮牛牛吧。

思路:先找到子序列中的最大值,再找到次大值,然后异或。整数可能是负数。针对每一个数,将其看作某连续子序列的次大值,这样就搜索了所有的可能性。找到最近的前后两个比其大的数作为最大值,求异或值。拆分:连续子序列是由每一个数字组成的,遍历当前的数字时,就假设它是次大值,它的左边或者右边  找到比它大的值。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> num;
 
int main()
{
    int n;
    cin>>n;//输入N
    for(int i=0;i<n;++i)
    {
        int tmp;//TMP记录序列中的每个索引的值
        cin>>tmp;
        num.push_back(tmp);//放入
    }
    int res = 0;
    for(int i=0;i<n;++i)
    {
        for(int j=i-1;j>=0;--j)//每次都是两个比,和左边的数字比较,
        {
            //找到就break,因为num[i]作为次大值
            if(num[j] > num[i])
            {
                res = max(res,num[j]^num[i]);
                break;
            }
        }
        for(int j=i+1;j<n;++j)//和右边的比较大小
        {
            if(num[j] > num[i])
            {
                res = max(res,num[j]^num[i]);
                break;
            }
        }
    }
    cout<<res<<endl;
    return 0;
}//注意两次循环比较左边和右边的写法,有没有更好的算法呢?

 

给定一个由n个点,m条边组成的无向图(注意,此图可能不连通),对任意1 ≤ i ≤ m存在一条边连接u[i], v[i]。回答此图是不是二分图。二分图定义为存在一种给图中每一个点染上黑白两色其中之一的着色方式,使得对每一对有边直接相连的点颜色不同。 

关于图的存储常用两种:邻接矩阵和邻接表;图的遍历有三种:BFS,DFS递归,DFS非递归。所以图的存储和图的遍历共有6种组合。

python:两个字典(哈希表),装纳两个二分图中的点。如果有两个点同时在一个字典中就输出False

链接:https://www.nowcoder.com/questionTerminal/f4b8d0481c7b4278b9b406b636e3c7db
来源:牛客网

import sys
def test_binary(num):
    dic1 = {}
    dic2 = {}
    for i in num:
        if (i[0] in dic1 and i[1] in dic1) or (i[0] in dic2 and i[1] in dic2):
            return False
        else:
            if i[0] in dic1:
                dic2[i[1]] = dic2.get(i[1],0)+1
            elif i[0] in dic2:
                dic1[i[1]] = dic1.get(i[1],0)+1
            elif i[1] in dic1:
                dic2[i[0]] = dic2.get(i[0],0)+1
            elif i[1] in dic2:
                dic1[i[0]] = dic1.get(i[0],0)+1
            else:
                dic1[i[0]] = dic1.get(i[0],0)+1
                dic2[i[1]] = dic2.get(i[1],0)+1
    return True
if __name__=='__main__':
    n,m = list(map(int,input().split()))
    res = []
    for line in sys.stdin.readlines():
        temp = list(map(int,line.split()))
        res.append(temp)
    if test_binary(res):
        print('Yes')
    else:
        print('No')

HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少1)

思路:

这题目是最基础的动态规划的题目:最大子数组的和一定是由当前元素和之前最大连续子数组的和叠加在一起形成的,因此需要遍历n个元素,看看当前元素和其之前的最大连续子数组的和能够创造新的最大值。

需要设置两个变量来存结果,并实现更新。

例子分析:(1,-2,3,10,-4,7,2,-5)通过分析我发现,如果大于零,那么我继续累加就行;否则,则需要剔除原来的累加和重新开始。时间复杂度为O(n)

                                     

JS版本:

function FindGreatestSumOfSubArray(array)
{
    let curSum = 0, greateSum = array[0];
    array.forEach((value) => {
        if(curSum < 0) {
            curSum = value;//如果当前和小于0,直接把之前全部舍弃,新的存贮的值是当前索引的值
        } else {
            curSum += value;//否则就继续累加
        }
        if(curSum > greateSum) {
            greateSum = curSum;//更新最大值
        }
    })
    return greateSum;
}

C++ 

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        if(array.empty()){
            return 0;//边界条件
        }
        // 初始化变量,maxSum为最大和,curSum为当前和
        int maxSum = array[0];//一个是最大的和
        int curSum = array[0];//一个是当前的变量,这个当前的变量如果小于0的话,要抛弃前面的值
        // 遍历所有元素
        for(int i = 1; i < array.size(); i++){
            // 如果当前和小于等于0,说明之前的是负数,则抛弃前面的和,重新计算
            if(curSum <= 0){
                curSum = array[i];//之前的全部舍弃,当前存储的是只有一个数
            }
            // 如果没有问题,直接累加
            else{
                curSum += array[i];
            }
            // 更新最大和
            if(curSum > maxSum){
                maxSum = curSum;//更新最大值
            }
        }
        return maxSum;
    }
};

PYthon: 

class Solution:
    def FindGreatestSumOfSubArray(self, array):
        if len(array) == 0:
            return 0
        maxSum = array[0]
        curSum = array[0]
        
        for each in array[1:]:
            if curSum <= 0:
                curSum = each//之前舍弃,只存储数组中的当前索引下的数字值
            else:
                curSum += each
            if curSum > maxSum:
                maxSum = curSum
        return maxSum

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值