抽象概念一定要被具象化才能被理解吗?

转载自 https://www.yueyao1982.com/phil_faq/faq_abstraction.html 若侵犯了内容创作者的权益,请联系删除 正文: 恰恰相反,具体的问题一定要抽象化之后才能理解,虽然这乍听起来比较奇怪。我们不妨想一想中学物理中最简单的问题,比如斜面上物体的运动。我们是先把物体和斜面都作了抽象化——物体和斜面都有很多细节,即“象”,而这些“象”被我们忽略了,或者说是抽离了,亦即“抽象”。所以,我们通过牛顿力学来理解机械运动,只是在理解抽象物体的相互关系,比如它们之间的作用,即力,比如它们之间的相对运动:简而言之,我们是在研究一个抽象模型,并试图理解这个模型。我们能做到最好的,就是我们的抽象化很合理,亦即被抽掉的“象”都是次要的;相应的,我们能得到最好的结果就是:模型的预测结果和实际的观测结果之间误差很小,一般来说不能没有误差,除非被观测值的可能性是离散甚至是有限的——比如电子的自旋只有两种可能。即使我们真的把主要因素抽掉,我们仍然可以理解那个被抽象出来的模型,只是那个模型和经验世界已经不能很好的对应了。 稍微深入一些来说,并非所有的抽象概念都能具象化,或者说概念的世界至少从规则和可能性这些方面来讲,并不受制于经验的世界,虽然没有经验概念就无从产生。比如我们观察过很多“经验中的马”,忽略了彼此不同的“象”,比如颜色、大小、公母等因素,就产生了“马的概念”;同样,我们观察过很多“经验世界中的鸟”,忽略了彼此不同的“象”,就产生了“鸟的概念”。“马的概念”和“鸟的概念”都可以被具象化到自然界中真实的动物。然而,我们的思维还可以对概念进行加工,比如我们对“鸟”概念进行切分,得到了“翅膀的概念”(当然它还是可以被具象化的)。然后我们把“翅膀的概念”和“马的概念”进行组合,得到了“天马”的概念——这个概念虽然可以具象化为具体的玩具或模型,但不再能具象化为自然界中的动物了。与此相似,我们还可以进行更复杂的概念建构,比如用更多的翅膀构建出“六翼天使”,比如用多种动物的不同部分构建出了“龙”和“麒麟”等神兽。当然,到此为止,这些概念至少还是可以被在一定程度上具象化,比如画成图画,比如做成雕刻。但是,更进一步的概念建构使这点也不可能了。如果我们把自然数的计数泛化到空间的维度上,我们就构建出了N维空间——1维空间、2维空间和3维空间是可以被具象化的,4维...

leetcode——18.4sum题解

 题目要求:

18.4sum

    给出一个整型数组,寻找其中所有不同的子数组(a,b,c,d)使得a,b,c,d的和等于一个给定的数target

    代码:


       
class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        if (nums.size() < 4)
            return result; // If there are less than 4 elements, return empty result
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for (int i = 0; i < n - 3; ++i) {
            if (i > 0 && nums[i] == nums[i - 1]) // Skip duplicate elements
                continue;
            for (int j = i + 1; j < n - 2; ++j) {
                if (j > i + 1 && nums[j] == nums[j - 1]) // Skip duplicate elements
                    continue;
                int left = j + 1;
                int right = n - 1;
                while (left < right) {
                    long long sum = (long long)nums[i] + nums[j] + nums[left] + nums[right]; // Convert to long long to avoid overflow
                    if (sum == target) {
                        result.push_back({nums[i], nums[j], nums[left], nums[right]});
                        while (left < right && nums[left] == nums[left + 1]) // Skip duplicate elements
                            left++;
                        while (left < right && nums[right] == nums[right - 1]) // Skip duplicate elements
                            right--;
                        left++;
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        right--;
                    }
                }
            }
        }
        return result;
    }
};

      
	
	
	

前提

    1.要有nums.size()>=4
    2.target可以提供nums中的元素相加得到(要考虑没有结果的情况,本题中给出的数据是一定有结果的)
    3.数据大小的判定:比如这里的nums就是一个long long型变量而不是普通的int型(int型无法通过编译)

逻辑

    对撞指针,索引为left和right。
    
    索引i和索引j是两个无条件的循环,所需的时间复杂度是O(N^2)在j循环后又有一个对撞指针其时间复杂度是O(N)所以总共的时间复杂度为O(N^3)。
    时间复杂度有点高,为了降低时间复杂度,可以使用空间换时间(比如将nums[i]+nums[j]合成一个数据,开辟一个nums.size()*nums.size()的数组存放这些数据可以将时间复杂度将为O(N^2)现在的空间复杂度为:O(N^2)。)
    空间换时间是一种具体的方法。在很多情况下,时间比空间更重要。

此博客中的热门博文

算法的八大常用思想