算法题-列表相关

求一个列表中出现次数最多的元素

import collections
def test(nums):
    hashmap = collections.Counter(nums)
    print(hashmap)
    return max(hashmap, key=hashmap.get)
nums = [1,2,3,3,2,1,2,2,2,4]
print(test(nums))
public static void main(String[] args){
        int[] m = {1,2,1,2,3,3,4,4,4,4};
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i=0;i<m.length;i++){
            if(map.containsKey(m[i])){
                map.put(m[i],map.get(m[i])+1);
            } else {
                map.put(m[i], 1);
            }
        }
        int a=1;
        for(Integer i : map.keySet()){
            if(map.get(i)>a){
                a = map.get(i);
            }
        }
        System.out.println(a);
    }

写一个栈,要求实现push 和 pop 还有min max,且要求所有的操作是O(1)的

class MyStack():
    def __init__(self):
        self._alist = []
        self._index = 0
        self._min_list = []
        self._max_list = []


    def spush(self, term):
        if not self._alist :
            self._min_list.append(term)
            self._max_list.append(term)
        else:
            if term > self._min_list[self._index-1]:
                self._min_list.append(self._min_list[self._index-1])
            else:
                self._min_list.append(term)
            if term < self._max_list[self._index-1]:
                self._max_list.append(self._max_list[self._index-1])
            else:
                self._max_list.append(term)
        self._index += 1
        self._alist.append(term)


    def spop(self):
        if not self._alist:
            raise Exception('当前栈为空')
        self._alist.pop()
        self._min_list.pop()
        self._max_list.pop()
        self._index -= 1


    def smax(self):
        if not self._max_list:
            raise Exception('当前栈为空')
        return self._max_list[-1]


    def smin(self):
        if not self._min_list:
            raise Exception('当前栈为空')
        return self._min_list[-1]


    def get_alist(self):
        return self._alist

现在有3种硬币,面值分别是 1分 2分 5分,假设硬币的总数为n个(允许某一类是0个), 硬币的总面值为m,请求出硬币可能的组合有哪些?

def test(n, m):
    a = [1, 2, 5]
    # 如果n个5分硬币的值都小于m,说明无解
    if 5*n < m:
        return 0
    up = n*5
    down = 0
    if (m-n)/4 < up:
        up = (m-n)//4
    if (m-2*n) >=3:
        down = (m-n*2+2)/3
    return up-down +1

n = 5
m = 10
print(test(n, m))

列表中第二大元素值

def test(nums):
    # t1存最大值,t2存最小值
    if nums[0] > nums[1]:
        t1, t2 =  nums[0], nums[1]
    else:
        t2, t1 = nums[0], nums[1]
    for i in range(2, len(nums)):
        if nums[i] > t1:
            t1 = nums[i]
        elif nums[i]>t2:
            t2 = nums[i]
    return t2

多数元素

题目:给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
解析:一个列表中能超过列表长度二分之一的元素最多只有一个。
解法1:哈希法

import collections

def majorityElement(nums):
    hash_map = collections.Counter(nums)
    return max(hash_map, key = hash_map.get)

解法2:排序

def majorityElement(nums):
    sorted(nums)
    return nums[len(nums)//2]

解法3:随机法

import random
def majorityElement(nums):
    majority_count = len(nums)//2
    while True:
        candidate = random.choice(nums)
        if sum(1 for elem in nums if elem == candidate) > candidate:
            return candidate

杨辉三角

题目:给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
解法1:

def generate(num_rows):
    triangle = []

    for row_num in range(num_rows):
        # 生成一个列表,两边的值=1,中间的=none
        row = [None for _ in range(row_num + 1)]
        row[0], row[-1] = 1, 1

        # 取上一个列表中的元素两两相加,依次放入当前列表相应的位置
        for j in range(1, len(row) - 1):
            row[j] = triangle[row_num - 1][j - 1] + triangle[row_num - 1][j]
        triangle.append(row)
    return triangle

爬楼梯

题目:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
解法:递推
到第5个阶梯的方法数 = 4阶梯到5阶梯的方法数 + 3阶梯到5阶梯的方法数
f(n) = f(n-1)+f(n-2)

def climb_stairs(n):
    if n < 3:
        return n
    num_list = [0] *(n+1)
    num_list[1] = 1
    num_list[2] = 2
    for i in range(3, n+1):
        num_list[i] = num_list[i-1] + num_list[i-2]
s = climb_stairs(5)
print(s)

两个数组的交集 II

给定两个数组,编写一个函数来计算它们的交集。
方法1:迭代

import collections
def intersect(nums1, nums2):
    if len(nums1) > len(nums2):
        return intersect(nums2, nums1)
    temp = []
    hashmap = collections.Counter(nums2)
    for i in nums1:
        if i in hashmap.keys() and hashmap[i] > 0:
            temp.append(i)
            hashmap[i] -= 1
    return temp
nums1 = [1,2,3,3,2]
nums2 = [4,2,2]
p = intersect(nums1, nums2)
print(p)

方法2:排序

def intersect(nums1, nums2):
    nums1.sort()
    nums2.sort()
    i = 0
    j = 0
    temp = []
    while i<len(nums1) and j<len(nums2):
        if nums1[i] < nums2[j]:
            i += 1
        elif nums1[i] > nums2[j]:
            j += 1
        else:
            temp.append(nums1[i])
            i += 1
            j += 1
    return temp
nums1 = [1,2,3,4]
nums2 = [2,3,3,5]
m = intersect(nums1, nums2)
print(m)

合并两个有序数组

方法一 : 合并后排序

def merge(nums1, m, nums2, n):
    nums1[:] = sorted( nums1[:m]+ nums2)
    return nums1

nums1 = [1,2,3,0,0,0]
nums2 = [4,3]
v = merge(nums1, 3, nums2, 2)
print(v)

方法2:双指针,从前往后

def merge(nums1, m, nums2, n):
    nums1_copy = nums1[:m]
    nums1[:] = []
    p1 = 0
    p2 = 0
    while p1 < m and p2 < n:
        if nums1_copy[p1] < nums2[p2]:
            nums1.append(nums1_copy[p1])
            p1 += 1
        else:
            nums1.append(nums2[p2])
            p2 += 1
    if p1 < m:
        nums1[p1+p2:] = nums1_copy[p1:]
    if p2 < n:
        nums1[p1+p2:] = nums2[p2:]

nums1 = [1,2,3,0,0,0]
nums2 = [3,4]
m = 3
n = 2
merge(nums1, m, nums2, n)
print(nums1)

方法3:双指针,从后往前

def merge(nums1, m, nums2, n):
    p1 = m - 1
    p2 = n - 1
    p = m + n - 1
    while p1 >= 0 and p2 >= 0:
        if nums1[p1] < nums2[p2]:
            nums1[p] = nums2[p2]
            p2 -= 1
        else:
            nums1[p] = nums1[p1]
            p1 -= 1
        p -= 1
nums1 = [1,2,3,0,0,0]
nums2 = [3,4]
m = 3
n = 2
merge(nums1, m, nums2, n)
print(nums1)

加一

方法1:

def plusOne(digits):
    for i in range(len(digits)-1, -1, -1):
        if digits[i] != 9:
            digits[i] += 1
            return digits
        digits[i] = 0
    digits.insert(0, 1)
    return digits

print(plusOne([9,8,9]))

方法2:

def plusOne(digits):
    m = [int(x) for x in str(int(''.join(str(i) for i in digits))+1)]
    print(m)

方法3:

def plusOne(digits):
    sum = 0
    for i in digits:
        sum = sum * 10 + i
    return [int(x) for x in str(sum+1)]

print(plusOne([9,8,9]))

有效括号

def isVaild(s):
    stack = []
    mapping = {")":"(", "}":"{","]":"["}
    for char in s:
        if char in mapping:
            top_element = stack.pop() if stack else '#'
            if mapping[char] != top_element:
                return False
        else:
            stack.append(char)
    return not stack
nums = '{(}())[]'
p = isVaild(nums)
print(p)

旋转数组

方法1:反转

def rotate(s, k):
    n = len(s)
    k = k % n
    s.reverse()
    revers(s, 0, k-1)
    revers(s, k, n-1)
def revers(s, start, end):
    while start < end:
        s[start],s[end] = s[end],s[start]
        start += 1
        end -= 1
    print(s)
s = [1,2,3,4,5,6,7]
k = 3
rotate(s, k)

方法2:暴力法

def rotate(nums, k):
    for i in range(k):
        previous = nums[-1]
        for j in range(len(nums)):
            temp = nums[j]
            nums[j] = previous
            previous = temp
    print(nums)

s = [1,2,3,4,5,6,7]
k = 3
rotate(s, k)

方法3:使用额外的数组

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
阿里社招推荐和NLP算法工程师的笔试中可能会出现的算法有很多种,我将为你提供一个例子进行回答。 假设目要求设计一个基于协同过滤的电影推荐系统,根据用户的历史观影记录,为用户推荐其可能喜欢的电影。 首先,我们需要建立一个电影评分矩阵。矩阵的行表示用户,列表示电影,每个位置的值表示用户对该电影的评分。该评分矩阵可以通过采集用户行为数据和问卷调查的方式得到。 接下来,我们需要计算用户之间的相似度,然后为用户推荐那些和他们之前喜欢的电影相似的电影。常用的相似度计算方法有余弦相似度和皮尔逊相关系数。 具体算法步骤如下: 1. 对于一个指定用户,找到与其有相似观影记录的其他用户。 2. 根据这些相似用户的观影记录,计算推荐列表。 3. 根据推荐列表和已观看的电影,为该用户生成最终的推荐结果。 这个算法主要考察了协同过滤算法的应用,以及相似度计算的方法。同时,对于大规模的数据集,还可能需要考虑算法的优化和并行化处理。 总结起来,阿里社招推荐和NLP算法工程师笔试中的算法目涉及多种多样的问,需要候选人具备扎实的算法和数据结构基础,对相关领域的理论和实践有深入的了解,并能够灵活应用所学知识解决实际问。编程能力和思维的严密性也是评估的重要因素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值