2401. 最长优雅子数组

摘要
Title: 2401. 最长优雅子数组
Categories: 滑动窗口、位运算

Powered by:NEFU AB-IN

Link

2401. 最长优雅子数组

题意

给你一个由 正 整数组成的数组 nums 。

如果 nums 的子数组中位于 不同 位置的每对元素按位 与(AND)运算的结果等于 0 ,则称该子数组为 优雅 子数组。

返回 最长 的优雅子数组的长度。

子数组 是数组中的一个 连续 部分。

注意:长度为 1 的子数组始终视作优雅子数组

思路

滑动窗口优化,存在单调性,就是存在是或不是的分界线

  1. 子数组中任意两个数按位与均为 0,意味着任意两个数对应的集合的交集为空,题目的意思也就是说,这个数组里的数二进制位按位加起来,每一位二进制位最多为1
  2. 也就是这个集合中某个二进制位不能超过1,固定右端点,当来的值和集合维护的值进行AND运算>0,说明集合存在交集,所以指针左移,排除掉
  3. OR的操作用来给集合取并集,XOR的操作用来除去某个数的影响,也就是差
  4. 当维护好了,左边都是不符合,右边是符合,那么当前就是以r为右端点,最长的子数组

https://leetcode.cn/problems/longest-nice-subarray/solutions/1799426/bao-li-mei-ju-pythonjavacgo-by-endlessch-z6t6/

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# 3.8.19 import
import random
from collections import Counter, defaultdict, deque
from datetime import datetime, timedelta
from functools import lru_cache
from heapq import heapify, heappop, heappush, nlargest, nsmallest
from itertools import combinations, compress, permutations, starmap, tee
from math import ceil, comb, fabs, floor, gcd, log, perm, sqrt
from string import ascii_lowercase, ascii_uppercase
from sys import exit, setrecursionlimit, stdin
from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union

# Constants
TYPE = TypeVar('TYPE')
N = int(2e5 + 10)
M = int(20)
INF = int(1e12)
OFFSET = int(100)
MOD = int(1e9 + 7)

# Set recursion limit
setrecursionlimit(int(2e9))


class Arr:
array = staticmethod(lambda x=0, size=N: [x() if callable(x) else x for _ in range(size)])
array2d = staticmethod(lambda x=0, rows=N, cols=M: [Arr.array(x, cols) for _ in range(rows)])
graph = staticmethod(lambda size=N: [[] for _ in range(size)])


class Math:
max = staticmethod(lambda a, b: a if a > b else b)
min = staticmethod(lambda a, b: a if a < b else b)


class IO:
input = staticmethod(lambda: stdin.readline().rstrip("\r\n"))
read = staticmethod(lambda: map(int, IO.input().split()))
read_list = staticmethod(lambda: list(IO.read()))


class Std:
pass
# ————————————————————— Division line ——————————————————————


class Solution:
def longestNiceSubarray(self, nums: List[int]) -> int:
l, ans, or_ = 0, 1, 0
for r, num in enumerate(nums):
while or_ & num:
or_ ^= nums[l]
l += 1
or_ |= num
ans = Math.max(ans, r - l + 1)
return ans


class Bit(int):
def __new__(cls, value):
return super(Bit, cls).__new__(cls, value)

def __init__(self, value):
self.bin_rep = bin(value)[2:]

def bit_length(self): return len(self.bin_rep)
def bit_count(self): return self.bin_rep.count('1')
def lowest1(self): return Bit(self & -self)
def lowest0(self): return Bit(~self & (self + 1))
def clear_lowest1(self): return Bit(self & (self - 1))
def clear_lowest0(self): return Bit(self | (self + 1))
def get_bits(self, start, end): return self & Bit.range_mask(start, end)
def __or__(self, other): return Bit(super(Bit, self).__or__(other))
def __and__(self, other): return Bit(super(Bit, self).__and__(other))
def __sub__(self, other): return Bit(super(Bit, self).__and__(~other))

all_ones_mask = staticmethod(lambda length: (1 << length) - 1)
all_zeros_mask = staticmethod(lambda length: 0)
single_bit_mask = staticmethod(lambda position: 1 << position)
range_mask = staticmethod(lambda start, end: ((1 << (end - start + 1)) - 1) << start)

# ————————————————————— Division line ——————————————————————


class Solution:
def longestNiceSubarray(self, nums: List[int]) -> int:
l, ans, or_ = 0, 1, Bit(0)
for r, num in enumerate(nums):
bit_num = Bit(num)
while or_ & bit_num:
or_ -= Bit(nums[l])
l += 1
or_ |= Bit(num)
ans = Math.max(ans, r - l + 1)
return ans
使用搜索:谷歌必应百度