代码(二) 手链有m个珠子共n种颜色

题目一

一个手链有m个珠子共n种颜色,找出包含n种颜色的最短连续片段。例如手链[1,2,2,2,2,2,2,0],它的最短连续片段数为3。

暴力破解

遍历所有可能性,时间复杂度 O ( m n 2 ) O(mn^2) O(mn2)

方法一

使用双指针的方法,记为 s t a r t = 0 start=0 start=0 e n d = 0 end=0 end=0

  • 向右移动 e n d end end,直到 [ s t a r t , e n d ] [start, end] [start,end]中包含 m m m种颜色的珠子
  • 循环
    • s t a r t + = 1 start += 1 start+=1
    • [ s t a r t , e n d ] [start, end] [start,end]中,包含 m m m种颜色的珠子,更新最小值
    • [ s t a r t , e n d ] [start, end] [start,end]中,小于 m m m种颜色的珠子,移动 e n d end end
  • 终止

具体代码如下所示

from collections import defaultdict


def get_length(cate2num):
  return len([cate for cate, num in cate2num.items() if num != 0])


def function(input_array, m, n):
  head, tail = 0, 0
  min_size = 1e10
  length = len(input_array)
  cate2num = defaultdict(int)
  while(head < len(input_array)):
    # 更新tail指针
    while(get_length(cate2num) != n):
      index = tail % length
      cate2num[input_array[index]] += 1
      tail += 1
    # 更新head指针
    min_size = min(min_size, tail - head)
    # 更新数值
    cate2num[input_array[head]] -= 1
    head += 1
  return min_size

题目二

有m个米家,n个米粉,求这些米粉到米家的最短距离。为了简化问题,假设所有这些设施都在一条直线,例如米家为 [ 5 , 3 , 2 ] [5,3,2] [5,3,2],米粉为 [ 1 , 3 , 4 ] [1,3,4] [1,3,4],此时最短距离为 2 2 2

方法

将米家和米粉分别排序,然后从左往右、从右往左遍历两遍,两个数组最小值加和即为结果。

代码

def min_size(shops, customers):
  shops = sorted(shops)
  customers = sorted(customers)
  # 从左到右
  j, left_buff = 0, []
  for i in range(len(customers)):
    # 更新
    while(j < len(shops) and customers[i] > shops[j]):
      j += 1
    left_buff.append(shops[j] - customers[i] if j < len(shops) else 1e10)
  # 从右到左
  j, right_buff = len(shops) - 1, []
  for i in range(len(customers) - 1, -1, -1):
    # 更新
    while(j >= 0 and customers[i] < shops[j]):
      j -= 1
    right_buff.append(customers[i] - shops[j] if j >= 0 else 1e10)
  right_buff = right_buff[::-1]
  return sum([min(l, r) for l, r in zip(right_buff, left_buff)])

题目三

给定一个非降序列 i n p u t _ a r r a y input\_array input_array和一个数值 v v v,请给出 i n p u t _ a r r a y input\_array input_array v v v的下一个元素的 i n d e x index index。例如 [ 1 , 2 , 2 , 2 , 3 ] [1,2,2,2,3] [1,2,2,2,3]返回值为 4 4 4

方法

二分查找,迭代更新

代码


def func(input_array, m):
  # 边界条件
  if(m < input_array[0]):
    return -1
  if(m >= input_array[-1]):
    return -1
  # 二分查找
  start, end = 0, len(input_array) - 1
  while(start <= end):
    mid = int((start + end) / 2)
    if(input_array[mid] < m):
      start = mid + 1
      continue
    elif(input_array[mid] > m):
      end = mid - 1
      continue
    elif(input_array[mid] == m and input_array[mid] == input_array[mid + 1]):
      start = mid + 1
      end = len(input_array) - 1
    else:
      return mid + 1
  return -1

题目四

深度遍历/广度遍历/前序遍历/中序遍历

方法

代码

深度遍历/前序遍历(非递归)

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
      vector<int> result;
      if(root == NULL)
        return result;      
      stack<TreeNode*> storage;
      storage.push(root);
      while(storage.size() != 0){
        TreeNode* pointer = storage.top();
        storage.pop();
        result.push_back(pointer -> val);
        if(pointer -> right != NULL)
          storage.push(pointer -> right);
        if(pointer -> left != NULL)
          storage.push(pointer -> left);
      }
      return result;        
    }
};

广度遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
      vector<vector<int>> result;
      if(root == NULL)
        return result;
      queue<TreeNode*> storage;
      storage.push(root);
      while(storage.size() != 0){
        vector<int> buff;
        int size = storage.size();
        for(int i=0; i<size; i++){
          TreeNode* pointer = storage.front();
          storage.pop();
          buff.push_back(pointer -> val);
          if(pointer -> left != NULL)
            storage.push(pointer -> left);
          if(pointer -> right != NULL)
            storage.push(pointer -> right);
        }
        result.push_back(buff);
      }
      return result;
    }
};

中序遍历

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
      vector<int> result;
      stack<TreeNode*> storage;
      TreeNode* pointer = root;
      while(pointer != NULL || storage.size() != 0){
        if(pointer == NULL){
          pointer = storage.top();
          storage.pop();
          result.push_back(pointer -> val);
          pointer = pointer -> right;
        }else{
          storage.push(pointer);
          pointer = pointer -> left;
        }
      }
      return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值