Slice Wood

本文介绍了一种通过二分查找算法来解决木材切割问题的方法,旨在将原木切割为尽可能长且数量固定的小段木头。文章详细解释了算法的具体实现过程。
描述


木材厂有一些原木,现在想把这些木头切割成一些长度相同的小段木头,需要得到的小段的数目


是给定了。当然,我们希望得到的小段越长越好,你的任务是计算能够得到的小段木头的最大长


度。


木头长度的单位是厘米。原木的长度都是正整数,我们要求切割得到的小段木头的长度也要求是


正整数。


例如输入 A = {232, 124, 456}, targetNum = 7

意思是,有3段原木,长度分别是 232, 124, 456, 希望通过切割后得到7根木头,每根的长度一样(并且做到长度尽量长)。


// given len of each slice, return total number of slice could get
public int getSlices(int[] A, int eachLen) {
    int count = 0;
    for (int i = 0; i < A.length; i++) {
        count += A[i] / eachLen;
    }
    return count;
}

public int sliceWood(int[] A, int targetNum) {
    if (A == null || A.length == 0) {
        return 0;
    }
    
    int max = 0;
    for (int i = 0; i < A.length; i++) {
        if (A[i] > max) {
            max = A[i];
        }
    }
    
    int left = 0;
    int right = max;
    int mid;
    
    while (left + 1 < right) {
        mid = left + (right - left) / 2;
        int sliceNum = getSlices(A, mid);
        
        if (sliceNum == targetNum) {
        // 找到符合要求的长度后,不能立刻停止,而要继续往右找,因为需要做到每根长度是可能做到的最长
            left = mid;
        } else if (sliceNum < targetNum) {
            right = mid;
        } else {
            left = mid;
        }
    }
    
    int rightNum = getSlices(A, right);
    int leftNum = getSlices(A, left);
    
    if (rightNum == targetNum) {
        return right;
    }
    if (leftNum == targetNum) {
        return left;
    }
    
    return 0;
}


思路是,先找到所有原木中长度的最大值。

然后 left = 0, right = 原木最大值,进行二分查找。

但是, 找到一个符合要求的切割长度,却并不一定是最优解。因为题目要求做到这个切割长度是尽量长的。

所以在找到一个符合要求的切割长度后,任然继续向右找。

这样在跳出后,right 和 left 上肯定至少有一个保留有符合要求的,并且是最大的长度。

优先比较right, 因为如果right 和 left 都符合要求, right的长度更长

['Order', 'PID', 'MS SubClass', 'MS Zoning', 'Lot Frontage', 'Lot Area', 'Street', 'Alley', 'Lot Shape', 'Land Contour', 'Utilities', 'Lot Config', 'Land Slope', 'Neighborhood', 'Condition 1', 'Condition 2', 'Bldg Type', 'House Style', 'Overall Qual', 'Overall Cond', 'Year Built', 'Year Remod/Add', 'Roof Style', 'Roof Matl', 'Exterior 1st', 'Exterior 2nd', 'Mas Vnr Type', 'Mas Vnr Area', 'Exter Qual', 'Exter Cond', 'Foundation', 'Bsmt Qual', 'Bsmt Cond', 'Bsmt Exposure', 'BsmtFin Type 1', 'BsmtFin SF 1', 'BsmtFin Type 2', 'BsmtFin SF 2', 'Bsmt Unf SF', 'Total Bsmt SF', 'Heating', 'Heating QC', 'Central Air', 'Electrical', '1st Flr SF', '2nd Flr SF', 'Low Qual Fin SF', 'Gr Liv Area', 'Bsmt Full Bath', 'Bsmt Half Bath', 'Full Bath', 'Half Bath', 'Bedroom AbvGr', 'Kitchen AbvGr', 'Kitchen Qual', 'TotRms AbvGrd', 'Functional', 'Fireplaces', 'Fireplace Qu', 'Garage Type', 'Garage Yr Blt', 'Garage Finish', 'Garage Cars', 'Garage Area', 'Garage Qual', 'Garage Cond', 'Paved Drive', 'Wood Deck SF', 'Open Porch SF', 'Enclosed Porch', '3Ssn Porch', 'Screen Porch', 'Pool Area', 'Pool QC', 'Fence', 'Misc Feature', 'Misc Val', 'Mo Sold', 'Yr Sold', 'Sale Type', 'Sale Condition', 'SalePrice'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) File /opt/conda/envs/anaconda-2024.02-py310/lib/python3.10/site-packages/pandas/core/indexes/base.py:3791, in Index.get_loc(self, key) 3790 try: -> 3791 return self._engine.get_loc(casted_key) 3792 except KeyError as err: File index.pyx:152, in pandas._libs.index.IndexEngine.get_loc() File index.pyx:181, in pandas._libs.index.IndexEngine.get_loc() File pandas/_libs/hashtable_class_helper.pxi:7080, in pandas._libs.hashtable.PyObjectHashTable.get_item() File pandas/_libs/hashtable_class_helper.pxi:7088, in pandas._libs.hashtable.PyObjectHashTable.get_item() KeyError: 'LotFrontage' The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) Cell In[11], line 30 27 df.loc[(df['Neighborhood'] == neighborhood) & (df['LotFrontage'].isnull()), 'LotFrontage'] = median 28 return df ---> 30 df = impute_lot_frontage(df) 32 df['HouseAge'] = df['Yr Sold'] - df['Year Built'] 33 df['RemodelAge'] = df['Yr Sold'] - df['Year Remod/Add'] Cell In[11], line 26, in impute_lot_frontage(df) 24 def impute_lot_frontage(df): 25 for neighborhood in df['Neighborhood'].unique(): ---> 26 median = df[df['Neighborhood'] == neighborhood]['LotFrontage'].median() 27 df.loc[(df['Neighborhood'] == neighborhood) & (df['LotFrontage'].isnull()), 'LotFrontage'] = median 28 return df File /opt/conda/envs/anaconda-2024.02-py310/lib/python3.10/site-packages/pandas/core/frame.py:3893, in DataFrame.__getitem__(self, key) 3891 if self.columns.nlevels > 1: 3892 return self._getitem_multilevel(key) -> 3893 indexer = self.columns.get_loc(key) 3894 if is_integer(indexer): 3895 indexer = [indexer] File /opt/conda/envs/anaconda-2024.02-py310/lib/python3.10/site-packages/pandas/core/indexes/base.py:3798, in Index.get_loc(self, key) 3793 if isinstance(casted_key, slice) or ( 3794 isinstance(casted_key, abc.Iterable) 3795 and any(isinstance(x, slice) for x in casted_key) 3796 ): 3797 raise InvalidIndexError(key) -> 3798 raise KeyError(key) from err 3799 except TypeError: 3800 # If we have a listlike key, _check_indexing_error will raise 3801 # InvalidIndexError. Otherwise we fall through and re-raise 3802 # the TypeError. 3803 self._check_indexing_error(key) KeyError: 'LotFrontage'
06-16
在IT领域中,"slice" 一词通常与编程语言中的数据结构和操作相关。以下是对 "slice" 的详细解释: ### 数据结构中的 Slice 在编程语言中(如Go、Python等),**Slice 是一种灵活的数据结构**,用于表示对底层数组的抽象。它通常包含三个核心组成部分: 1. **指针(Pointer)**:指向底层数组的起始位置。 2. **长度(Length, len)**:表示当前 Slice 中元素的数量。 3. **容量(Capacity, cap)**:表示从指针开始到底层数组末尾的元素总数。 例如,在 Go 语言中,可以使用 `make` 函数创建 Slice: ```go slice := make([]int, 5, 10) ``` 上述代码创建了一个长度为 5、容量为 10 的整型 Slice。底层数组会分配足够的空间以容纳 10 个元素,但当前 Slice 只能访问前 5 个元素[^2]。 ### Slice 的常见操作 1. **初始化 Slice** - 使用字面量直接定义: ```go slice := []int{1, 2, 3} ``` - 使用 `make` 函数指定长度和容量: ```go slice := make([]int, 5, 10) ``` - 初始化时底层调用 `runtime.makeslice` 来分配内存[^1]。 2. **扩展 Slice** - 使用 `append` 操作向 Slice 添加元素。当 Slice长度超过容量时,底层数组会被重新分配更大的空间,并将旧数据复制过去。此过程涉及 `runtime.growslice` 的调用。 3. **切片操作** - 使用索引操作获取子 Slice,例如: ```go subSlice := slice[2:5] ``` 此操作不会复制底层数组,而是创建一个新的 Slice 结构体,指向原数组的一部分。 ### 其他上下文中的 Slice 1. **字符串操作中的 Slice** - 在 JavaScript 等语言中,`slice()` 方法用于提取字符串的部分内容。例如: ```javascript var str = "Hello,world!"; var sliceStr = str.slice(1, 5); // 输出 "ello" ``` `slice(start, end)` 方法支持负数索引,例如: ```javascript var sliceStr = str.slice(-3); // 输出 "rld!" ``` 这种方法常用于处理字符串片段[^3]。 2. **Slice 与其他方法的区别** - `slice(start, end)` 和 `substring(start, end)` 类似,但不支持负数索引。 - `substr(start, length)` 则是根据起始位置和长度提取字符串。 ### Slice 的性能特性 - **高效性**:Slice 不需要频繁分配新内存,因为它可以复用底层数组。 - **动态扩容**:当通过 `append` 扩展 Slice 超出容量时,系统会自动调整底层数组的大小,通常是按指数增长策略。 - **零拷贝设计**:Slice 的切片操作不会复制数据,仅改变指针、长度和容量,因此效率非常高。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值