Leetcode 479~486题

第四百七十九题:

class Solution {
public:
    int largestPalindrome(int n) {
        typedef long long LL;
        if (n == 1) return 9;
        int maxv = pow(10, n) - 1;
        for (int i = maxv; ;i -- ) {
            auto a = to_string(i);
            auto b = a;
            reverse(b.begin(), b.end());
            auto num = stoll(a + b);
            for (LL j = maxv; j * j >= num; j -- )
                if (num % j == 0)
                    return num % 1337;
        }
        return 0;
    }
};
class Solution {
    public int largestPalindrome(int n) {
        if(n == 1) return 9;
        //计算给定位数的最大值
        long max = (long)Math.pow(10,n) - 1;
        //从max - 1开始循环,原因见上文
        for(long i = max - 1; i > max / 10; i--){
            //1. 构造回文数
            String s1 = String.valueOf(i);
            long rev = Long.parseLong(s1 + new StringBuilder(s1).reverse().toString());
            //2. 检验该回文数能否由给定的数相乘得到
            for(long x = max; x * x >= rev; x --){
                if(rev % x == 0) return (int)(rev % 1337);
            }
        }
        return -1;
    }
}
class Solution:
    def largestPalindrome(self, n: int) -> int:
        if n == 1: return 9
        a = 2
        hi = 10 ** n - 1
        lo = 10 ** (n - 1)
        while a < 2 * 10 ** n:
            upper = 10 ** n - a
            lower = int(str(upper)[::-1])
            if a ** 2 - 4 * lower >= 0 and (a ** 2 - 4 * lower) ** 0.5 == int((a ** 2 - 4 * lower)**0.5):
                num = int(str(upper)+ str(upper)[::-1])
                return num % 1337
            a += 1
var largestPalindrome = function (n) {
  if (n === 1) return 9;
  if (n === 8) return 475;
  for (let end = +(new Array(n).fill(9).join('')), i = end - 1; i >= 1; --i) {
    let num = +(i + i.toString().split('').reverse().join(''))
    for (let temp = end, start = Math.ceil(Math.sqrt(num)); temp >= start; --temp) {
      if (num % temp === 0) {
        return num % 1337
      }
    }
  }
};

第四百八十题:

class Solution {
public:
    int k;
    multiset<int> left, right;

    double get_medium() {
        if (k % 2) return *right.begin();
        return ((double)*left.rbegin() + *right.begin()) / 2;
    }

    vector<double> medianSlidingWindow(vector<int>& nums, int _k) {
        k = _k;
        for (int i = 0; i < k; i ++ ) right.insert(nums[i]);
        for (int i = 0; i < k / 2; i ++ ) {
            left.insert(*right.begin());
            right.erase(right.begin());
        }
        vector<double> res;
        res.push_back(get_medium());
        for (int i = k; i < nums.size(); i ++ ) {
            int x = nums[i], y = nums[i - k];
            if (x >= *right.begin()) right.insert(x);
            else left.insert(x);
            if (y >= *right.begin()) right.erase(right.find(y));
            else left.erase(left.find(y));

            while (left.size() > right.size()) {
                right.insert(*left.rbegin());
                left.erase(left.find(*left.rbegin()));
            }
            while (right.size() > left.size() + 1) {
                left.insert(*right.begin());
                right.erase(right.begin());
            }
            res.push_back(get_medium());
        }
        return res;
    }
};
class Solution {
    public double[] medianSlidingWindow(int[] nums, int k) {
        DualHeap dh = new DualHeap(k);
        for (int i = 0; i < k; ++i) {
            dh.insert(nums[i]);
        }
        double[] ans = new double[nums.length - k + 1];
        ans[0] = dh.getMedian();
        for (int i = k; i < nums.length; ++i) {
            dh.insert(nums[i]);
            dh.erase(nums[i - k]);
            ans[i - k + 1] = dh.getMedian();
        }
        return ans;
    }
}

class DualHeap {
    // 大根堆,维护较小的一半元素
    private PriorityQueue<Integer> small;
    // 小根堆,维护较大的一半元素
    private PriorityQueue<Integer> large;
    // 哈希表,记录「延迟删除」的元素,key 为元素,value 为需要删除的次数
    private Map<Integer, Integer> delayed;

    private int k;
    // small 和 large 当前包含的元素个数,需要扣除被「延迟删除」的元素
    private int smallSize, largeSize;

    public DualHeap(int k) {
        this.small = new PriorityQueue<Integer>(new Comparator<Integer>() {
            public int compare(Integer num1, Integer num2) {
                return num2.compareTo(num1);
            }
        });
        this.large = new PriorityQueue<Integer>(new Comparator<Integer>() {
            public int compare(Integer num1, Integer num2) {
                return num1.compareTo(num2);
            }
        });
        this.delayed = new HashMap<Integer, Integer>();
        this.k = k;
        this.smallSize = 0;
        this.largeSize = 0;
    }

    public double getMedian() {
        return (k & 1) == 1 ? small.peek() : ((double) small.peek() + large.peek()) / 2;
    }

    public void insert(int num) {
        if (small.isEmpty() || num <= small.peek()) {
            small.offer(num);
            ++smallSize;
        } else {
            large.offer(num);
            ++largeSize;
        }
        makeBalance();
    }

    public void erase(int num) {
        delayed.put(num, delayed.getOrDefault(num, 0) + 1);
        if (num <= small.peek()) {
            --smallSize;
            if (num == small.peek()) {
                prune(small);
            }
        } else {
            --largeSize;
            if (num == large.peek()) {
                prune(large);
            }
        }
        makeBalance();
    }

    // 不断地弹出 heap 的堆顶元素,并且更新哈希表
    private void prune(PriorityQueue<Integer> heap) {
        while (!heap.isEmpty()) {
            int num = heap.peek();
            if (delayed.containsKey(num)) {
                delayed.put(num, delayed.get(num) - 1);
                if (delayed.get(num) == 0) {
                    delayed.remove(num);
                }
                heap.poll();
            } else {
                break;
            }
        }
    }

    // 调整 small 和 large 中的元素个数,使得二者的元素个数满足要求
    private void makeBalance() {
        if (smallSize > largeSize + 1) {
            // small 比 large 元素多 2 个
            large.offer(small.poll());
            --smallSize;
            ++largeSize;
            // small 堆顶元素被移除,需要进行 prune
            prune(small);
        } else if (smallSize < largeSize) {
            // large 比 small 元素多 1 个
            small.offer(large.poll());
            ++smallSize;
            --largeSize;
            // large 堆顶元素被移除,需要进行 prune
            prune(large);
        }
    }
}
class DualHeap:
    def __init__(self, k: int):
        # 大根堆,维护较小的一半元素,注意 python 没有大根堆,需要将所有元素取相反数并使用小根堆
        self.small = list()
        # 小根堆,维护较大的一半元素
        self.large = list()
        # 哈希表,记录「延迟删除」的元素,key 为元素,value 为需要删除的次数
        self.delayed = collections.Counter()

        self.k = k
        # small 和 large 当前包含的元素个数,需要扣除被「延迟删除」的元素
        self.smallSize = 0
        self.largeSize = 0


    # 不断地弹出 heap 的堆顶元素,并且更新哈希表
    def prune(self, heap: List[int]):
        while heap:
            num = heap[0]
            if heap is self.small:
                num = -num
            if num in self.delayed:
                self.delayed[num] -= 1
                if self.delayed[num] == 0:
                    self.delayed.pop(num)
                heapq.heappop(heap)
            else:
                break
    
    # 调整 small 和 large 中的元素个数,使得二者的元素个数满足要求
    def makeBalance(self):
        if self.smallSize > self.largeSize + 1:
            # small 比 large 元素多 2 个
            heapq.heappush(self.large, -self.small[0])
            heapq.heappop(self.small)
            self.smallSize -= 1
            self.largeSize += 1
            # small 堆顶元素被移除,需要进行 prune
            self.prune(self.small)
        elif self.smallSize < self.largeSize:
            # large 比 small 元素多 1 个
            heapq.heappush(self.small, -self.large[0])
            heapq.heappop(self.large)
            self.smallSize += 1
            self.largeSize -= 1
            # large 堆顶元素被移除,需要进行 prune
            self.prune(self.large)

    def insert(self, num: int):
        if not self.small or num <= -self.small[0]:
            heapq.heappush(self.small, -num)
            self.smallSize += 1
        else:
            heapq.heappush(self.large, num)
            self.largeSize += 1
        self.makeBalance()

    def erase(self, num: int):
        self.delayed[num] += 1
        if num <= -self.small[0]:
            self.smallSize -= 1
            if num == -self.small[0]:
                self.prune(self.small)
        else:
            self.largeSize -= 1
            if num == self.large[0]:
                self.prune(self.large)
        self.makeBalance()

    def getMedian(self) -> float:
        return float(-self.small[0]) if self.k % 2 == 1 else (-self.small[0] + self.large[0]) / 2


class Solution:
    def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]:
        dh = DualHeap(k)
        for num in nums[:k]:
            dh.insert(num)
        
        ans = [dh.getMedian()]
        for i in range(k, len(nums)):
            dh.insert(nums[i])
            dh.erase(nums[i - k])
            ans.append(dh.getMedian())
        
        return ans
type hp struct {
    sort.IntSlice
    size int
}
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
func (h *hp) Pop() interface{}   { a := h.IntSlice; v := a[len(a)-1]; h.IntSlice = a[:len(a)-1]; return v }
func (h *hp) push(v int)         { h.size++; heap.Push(h, v) }
func (h *hp) pop() int           { h.size--; return heap.Pop(h).(int) }
func (h *hp) prune() {
    for h.Len() > 0 {
        num := h.IntSlice[0]
        if h == small {
            num = -num
        }
        if d, has := delayed[num]; has {
            if d > 1 {
                delayed[num]--
            } else {
                delete(delayed, num)
            }
            heap.Pop(h)
        } else {
            break
        }
    }
}

var delayed map[int]int
var small, large *hp

func medianSlidingWindow(nums []int, k int) []float64 {
    delayed = map[int]int{} // 哈希表,记录「延迟删除」的元素,key 为元素,value 为需要删除的次数
    small = &hp{}           // 大根堆,维护较小的一半元素
    large = &hp{}           // 小根堆,维护较大的一半元素
    makeBalance := func() {
        // 调整 small 和 large 中的元素个数,使得二者的元素个数满足要求
        if small.size > large.size+1 { // small 比 large 元素多 2 个
            large.push(-small.pop())
            small.prune() // small 堆顶元素被移除,需要进行 prune
        } else if small.size < large.size { // large 比 small 元素多 1 个
            small.push(-large.pop())
            large.prune() // large 堆顶元素被移除,需要进行 prune
        }
    }
    insert := func(num int) {
        if small.Len() == 0 || num <= -small.IntSlice[0] {
            small.push(-num)
        } else {
            large.push(num)
        }
        makeBalance()
    }
    erase := func(num int) {
        delayed[num]++
        if num <= -small.IntSlice[0] {
            small.size--
            if num == -small.IntSlice[0] {
                small.prune()
            }
        } else {
            large.size--
            if num == large.IntSlice[0] {
                large.prune()
            }
        }
        makeBalance()
    }
    getMedian := func() float64 {
        if k&1 > 0 {
            return float64(-small.IntSlice[0])
        }
        return float64(-small.IntSlice[0]+large.IntSlice[0]) / 2
    }

    for _, num := range nums[:k] {
        insert(num)
    }
    n := len(nums)
    ans := make([]float64, 1, n-k+1)
    ans[0] = getMedian()
    for i := k; i < n; i++ {
        insert(nums[i])
        erase(nums[i-k])
        ans = append(ans, getMedian())
    }
    return ans
}

第四百八十一题:

class Solution {
public:
    int magicalString(int n) {
        string s = "122";
        for (int i = 2, k = 1; s.size() < n; i ++, k = 3 - k) {
            for (int j = 0; j < s[i] - '0'; j ++ )
                s += to_string(k);
        }
        int res = 0;
        for (int i = 0; i < n; i ++ ) res += s[i] == '1';
        return res;
    }
};
class Solution {
  public int magicalString(int n) {
    if (n <= 0) return 0;
    if (n == 1) return 1;
    StringBuilder sb = new StringBuilder();
    sb.append(1);
    int cnt = 1, i = 1, low = 0;
    char cur = '1';
    while (i < n) {
      //填的数量就由走的慢的指针决定
      char former = sb.charAt(low++);
      //每次把一种数字填充完,如果上次填的1,那么这次就是2
      cur = cur == '1' ? '2' : '1';
      if (former == '1') {
        if (cur == '1') cnt++;
        sb.append(cur);
        i++;
      } else {
        if (cur == '1') cnt += 2;
        sb.append(cur);
        sb.append(cur);
        i += 2;
      }
    }
    //判断最后是否计入了 n 之后的 1,如有就去掉
    if (i == n && cur == '1') cnt--;
    if (i == n + 1 && cur == '1') cnt -= 2;
    return cnt;
  }
}
class Solution:
    def magicalString(self, n: int) -> int:
        a1 = [1, 2] + [0] * (n - 2)
        a2 = [1, 2, 2]
        i = 2
        while len(a2) < n:
            a1[i] = a2[i]
            a2.extend([3 - a2[-1]] * a1[i])
            i += 1
        return collections.Counter(a2[:n])[1]
func magicalString(n int) int {
    if n == 0 {
        return 0
    }
    s := make([]byte, 0, n+2)
    s = append(s, '1', '2', '2')
    next := 2
    res := 1
    for i := 2; i < n; i++ {
        if s[i] == '1' {
            res++
            if s[next] == '2' {
                s = append(s, '1')
            } else {
                s = append(s, '2')
            }
        } else {
            if s[next] == '2' {
                s = append(s, '1', '1')
            } else {
                s = append(s, '2', '2')  
            }
            next++
        }
        next++
    }

    return res
}

第四百八十二题:

class Solution {
public:
    string licenseKeyFormatting(string S, int K) {
        string s;
        for (auto c: S)
            if (c != '-')
                s += c;
        string res;
        for (int i = 0; i < s.size() % K; i ++ ) res += toupper(s[i]);
        for (int i = s.size() % K; i < s.size();) {
            if (res.size()) res += '-';
            for (int j = 0; j < K; j ++ )
                res += toupper(s[i ++ ]);
        }
        return res;
    }
};
class Solution {
    public String licenseKeyFormatting(String S, int K) {
        StringBuilder s = new StringBuilder();
        // 统计已打印字符个数
        int count = 0;
        // 倒序遍历字符串
        for (int i = S.length() - 1; i >= 0; i--) {
            if (S.charAt(i) != '-') {
                // 计算什么时候打印分隔符
                if (count != 0 && count % K == 0) {
                    s.append('-');
                }
                // 转为大写字母添加
                s.append(Character.toUpperCase(S.charAt(i)));
                count++;
            }
        }
        // 反转字符串
        return s.reverse().toString();
    }
}
class Solution:
    def licenseKeyFormatting(self, S: str, K: int) -> str:
        st = S.replace('-','').upper()
        a = len(st)
        if a == 0:
            return ''
        b = a%K
        if b == 0:
            c = (a//K) - 1
            b = K
        else:
            c = a//K
        s = st[:b]
        while c != 0:
            s += '-' + st[b:b+K]
            b = b+K
            c -= 1
        return s
func licenseKeyFormatting(S string, K int) string {
	str := strings.ReplaceAll(S,"-","")
	for i := len(str) - K; i > 0; i -= K {
		str = str[:i] + "-" + str[i:]
	}
	return strings.ToUpper(str)
}

第四百八十三题:

class Solution {
public:
    string smallestGoodBase(string number) {
        typedef long long LL;
        LL n = stoll(number);
        for (int t = log2(n) + 1; t >= 3; t -- ) {
            LL k = pow(n, 1.0 / (t - 1));
            LL r = 0;
            for (int i = 0; i < t; i ++ ) r = r * k + 1;
            if (r == n) return to_string(k);
        }
        return to_string(n - 1);
    }
};
public String smallestGoodBase(String n) {
        long N = Long.parseLong(n);
        for (int m = 59; m > 1; m--) {
            long k = (long) Math.pow(N, 1.0 / m);
            //不存在1进制,如果k<=1,直接下一次
            if (k <= 1)
                continue;
            long s = 0;
            for (int i = 0; i <= m; i++) 
                s = s * k + 1;
            if (s == N) 
                return String.valueOf(k);
        }
        return String.valueOf(N - 1);
    }
class Solution:
    def smallestGoodBase(self, n: str) -> str:
        n = int(n)
        # 上面提到的 base 进制转十进制公式。
        # 使用等比数列求和公式可简化时间复杂度
        def sum_with(base, N):
            return (1 - base ** N) // (1 - base)
            # return sum(1 * base ** i for i in range(N))
        # bin(n) 会计算出 n 的二进制表示, 其会返回形如 '0b10111' 的字符串,因此需要减去 2。
        for N in range(len(bin(n)) - 2, 0, -1):
            l = 2
            r = n - 1
            while l <= r:
                mid = (l + r) // 2
                v = sum_with(mid, N)

                if v < n:
                    l = mid + 1
                elif v > n:
                    r = mid - 1
                else:
                    return str(mid)
func smallestGoodBase(n string) string {
	s, _ := strconv.ParseInt(n, 10, 64)
	for i := 59; i >1; i-- {
		k:=int64(math.Pow(float64(s), 1.0/float64(i)))
        if k==1{
           continue
        }
		var temp int64
		for j := 0; j <= i; j++ {
			temp = temp*k+1
		}
		if temp ==s{
			return strconv.FormatInt(k, 10)
		}
	}
	return strconv.FormatInt(s-1, 10)
}

第四百八十五题:

class Solution {
public:
    int findMaxConsecutiveOnes(vector<int>& nums) {
        int res = 0;
        for (int i = 0; i < nums.size(); i ++ ) {
            if (nums[i] == 0) continue;
            int j = i + 1;
            while (j < nums.size() && nums[j] == 1) j ++ ;
            res = max(res, j - i);
            i = j;
        }
        return res;
    }
};
class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int maxCount = 0, count = 0;
        int n = nums.length;
        for (int i = 0; i < n; i++) {
            if (nums[i] == 1) {
                count++;
            } else {
                maxCount = Math.max(maxCount, count);
                count = 0;
            }
        }
        maxCount = Math.max(maxCount, count);
        return maxCount;
    }
}
class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        maxCount = count = 0

        for i, num in enumerate(nums):
            if num == 1:
                count += 1
            else:
                maxCount = max(maxCount, count)
                count = 0
        
        maxCount = max(maxCount, count)
        return maxCount
func findMaxConsecutiveOnes(nums []int) (maxCnt int) {
    cnt := 0
    for _, v := range nums {
        if v == 1 {
            cnt++
        } else {
            maxCnt = max(maxCnt, cnt)
            cnt = 0
        }
    }
    maxCnt = max(maxCnt, cnt)
    return
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

第四百八十六题:

class Solution {
public:
    bool PredictTheWinner(vector<int>& nums) {
        int n = nums.size();
        vector<vector<int>> f(n, vector<int>(n));
        for (int len = 1; len <= n; len ++ ) {
            for (int i = 0; i + len - 1 < n; i ++ ) {
                int j = i + len - 1;
                if (len == 1) f[i][j] = nums[i];
                else {
                    f[i][j] = max(nums[i] - f[i + 1][j], nums[j] - f[i][j - 1]);
                }
            }
        }
        return f[0][n - 1] >= 0;
    }
};
class Solution {
    public boolean PredictTheWinner(int[] nums) {
        int length = nums.length;
        int[] dp = new int[length];
        for (int i = 0; i < length; i++) {
            dp[i] = nums[i];
        }
        for (int i = length - 2; i >= 0; i--) {
            for (int j = i + 1; j < length; j++) {
                dp[j] = Math.max(nums[i] - dp[j], nums[j] - dp[j - 1]);
            }
        }
        return dp[length - 1] >= 0;
    }
}
class Solution:
    def PredictTheWinner(self, nums: List[int]) -> bool:
        length = len(nums)
        dp = [0] * length
        for i, num in enumerate(nums):
            dp[i] = num
        for i in range(length - 2, -1, -1):
            for j in range(i + 1, length):
                dp[j] = max(nums[i] - dp[j], nums[j] - dp[j - 1])
        return dp[length - 1] >= 0
func PredictTheWinner(nums []int) bool {
    length := len(nums)
    dp := make([]int, length)
    for i := 0; i < length; i++ {
        dp[i] = nums[i]
    }
    for i := length - 2; i >= 0; i-- {
        for j := i + 1; j < length; j++ {
            dp[j] = max(nums[i] - dp[j], nums[j] - dp[j - 1])
        }
    }
    return dp[length - 1] >= 0
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能say的秘密

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值