1. 程式人生 > >LeetCode 求和類演算法題目 詳解(C++)

LeetCode 求和類演算法題目 詳解(C++)

(樂樂獨家研製C++解決方法詳解,包含class詳解以及後期main呼叫)

1. two sum(這裡就擷取官網上的演算法題目--樂樂實在懶得打了)

leetcode官網演算法第一題

15. three sum

leetcode 官網演算法15題

兩道題一起講解~~嘻嘻

這道題目要求用的框架以及樂樂的答案:

#include<iostream>
using namespace std;
#include<vector> 
#include<algorithm>
class Solution {
 public:
  int temp=0 ;
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> result;
        if(nums.size()>=2)
        {
            for(int i=0;i<nums.size()-1;i++)
        {
            for(int j=i+1;j<nums.size();j++)
            {
                if(nums[i]+nums[j]==target)
                {
                    result.push_back(i+1);
                    result.push_back(j+1);
                    return result;
                }
            }
        }
        cout<<"meiyou "<<endl;
        return result;
        }

    }

    vector<vector<int> > threeSum(vector<int>& nums) 
 {
        vector<vector<int> > result(4);
        for(int i=0;i<4;i++)
        {
         result[i].resize(3);
        }

        int temp=0;
        for(int i=0;i<nums.size()-2;i++)
        {
         for(int j=i+1;j<nums.size()-1;j++)
         {
          for(int k=j+1;k<nums.size();k++)
          {
           if(nums[i]+nums[j]+nums[k]==0)
           {
            result[this->temp][0]=nums[i];
            result[this->temp][1]=nums[j];
            result[this->temp][2]=nums[k];
            //result[this->temp].push_back(nums[i]);
            //result[this->temp].push_back(nums[j]);
            //result[this->temp].push_back(nums[k]);
            this->temp++;
           }
          }
         }
        }
        return result;
    }

 vector<vector<int> > threeSum2(vector<int> &num) {
        vector<vector<int> > result;
  int i,j,k,n= num.size();
        sort(num.begin(),num.begin()+n);

        for(i=0;i<n-2;i++)
        {
         if(i>0&&num[i]==num[i-1])
         continue;

         j=i+1;
         k=n-1;
         while(j<k)
         {
          if(num[i]+num[j]+num[k]<0)
          {
           j++;
          }
          else if(num[i]+num[j]+num[k]>0)
          {
           k--;
          }
          else
          {
           vector <int> temp;
           temp.push_back(num[i]);
           temp.push_back(num[j]);
           temp.push_back(num[k]);
           result.push_back(temp);
     while(j<k&&num[k]==num[k-1])
           {
            k--;
           }
           while(j<k&&num[j]==num[j+1])
           {
            j++; 
     } 
     k--;
     j++;
          }

         }
        }

        return result;
    }
};
int main()
{
 /*
 vector<int> v1;
 vector<int> result;
 v1.push_back(12);
 v1.push_back(2);
 v1.push_back(15);
 v1.push_back(7);

 for(int i=0;i<v1.size();i++)
 {
  cout<<v1[i]<<"  ";
 } 
 cout<<endl;
 int target=9;
 Solution s; 
 result=s.twoSum(v1,target);
 for(int i=0;i<result.size();i++)
 {
  cout<<result[i]<<"  ";
 } */
 vector<int> v3;
 vector <vector<int> >result3;
 v3.push_back(-1);
 v3.push_back(0);
 v3.push_back(1);
 v3.push_back(2);
 v3.push_back(-1);
 v3.push_back(-4);
 Solution s3; 
 result3=s3.threeSum2(v3);
 for(int i=0;i<result3.size();i++)
 {
  for(int j=0;j<result3[i].size();j++)
  {
   cout<<result3[i][j]<<"  ";
  }
  cout<<endl;

 }
}

講解

1. 第一題相對簡單,主要是考察演算法應用,我一開始想到的就是雙迴圈,雖然不是最優解 O(n*n),但是可以實現功能的,一下就鞏固一下C++vector 的用法。

(1)首先,引用C++類庫:#include<vector>

(2) int &a=b 表示傳引用 說白了就是將地址傳給變數。→這就不難理解:vector <int> &num 這就相當於新定義一個只想num陣列(int num[n];)的首地址的vector型別資料。當然 大家肯定知道vector相當於動態陣列,比原本陣列擁有更多的靈活性,以及易操作性。

(3)二維陣列:vector <int *>num 這個我也沒實踐過,只是在網上知道這個知識點。以後用空試驗一下下。

(4)關於vector的常用函式。如果大家還想知道更多的可以自己百度一下下,我也是這麼學習的呢~~

    (4.1)num.push_back(20135606)→相當於在陣列最後面新增int 20135606(p.s.這是樂樂的學號啦,不要噴我~~)

    (4.2)my_num=num.push_pop();後面不加東西哈,表示彈出最後面的元素.

    (4.3) num.size(); 數目。

    (4.4)這是樂樂自己發現的問題哈,在使用devC++ 編譯的時候發現num[3]只能用於獲取 不能用於賦值:For instance: int LX=num[3]; 正確   However

: num[4]=23;報錯 我也不知道是怎麼回事,以後再問問大神吧~~

(5)迭代器 是一種檢查容器內元素 以及 遍歷元素的工具。不能使用下標訪問。(後期需要深入瞭解)

(6)下面進入程式碼邏輯,哈哈,這個有點簡單,就是雙重迴圈,再加上if判斷語句就好了~~

​2.leetcode15題 三個數字加起來等於0

(1)由於題目框架給的是vector二維陣列,那我們就瞭解一下這個吧:

定義:vector<vector <int>    > num(m)  注意我打出來的誇張的空格,所以你一定不要忘記呀。然後就是m。他表示的是一行有多少元素。

可以寫一個for迴圈處理每行 每列的大小:A[i].resize(10);每行10個。

(2)二維矩陣可以這樣賦值:A[0][0]=1; however: A[0].push_back(208);會報錯 因為只能單步push_back: A.push_back(1);

(3)class類內有成員屬性 temp ,後面類內函式呼叫temp的時候用 this->temp;(重要 請記住)

(4)邏輯邏輯邏輯 重要的事情說三遍:

    (4.1)我第一種想法(當然是錯誤想法)--三重迴圈,每次判斷是否有三個數滿足條件,但是這樣會有很多重複的結果~~為了避免這樣的事情發生,我們需要進行篩選。

(4.2)首先講一下我演算法的原理:

1. 從小到大的排序:用sort(num.begin(),num.begin()+n); 後面兩個引數主要是開始 和結束的範圍值,在網上沒有找到解釋的非常清楚的部落格,所以樂樂覺得有幾個排序數後面的n就加幾個,第一個是開始的最小的數值。

2.設定三個標籤 I, j, k。i就不用我多說 從第一個到最後一個遍歷,內層是J,K一個從前向後,一個從後向前,因為已經排序好,所以如果三個數值大於零,說明K太大了,k--;同理,如果小於零,J++;

3. 注意重複的結果,在處理過程中,只需要將I,j,k都用一個while語句判斷就可以了~~

這麼看起來其實中級難度的也就這樣,如果你喜歡我的文章麻煩點贊轉發呦~~樂樂謝謝您~~嘻嘻!!!

以上均為原創作品,如果喜歡請您轉發,盜版必究~~~