程序員進階之算法練習(一)


前言

可能很多移動端編程的同學聽到算法就感到恐懼,認為我不會算法也能開發呀。確實,不會算法,也能應對一般的工作。但是和大牛之間的差距就是,可能別人3行代碼實現的東西,你卻要寫10多行,並且性能比別人差。那么,讓我們來學習一些算法吧。

算法學習

算法的學習最簡單的方式就是多練習,找一個提供算法練習的網站,思考,編碼,驗證,最后再看看別人的思路。
本系列的題目來自LeetCode。IDE采用的Xcode,筆者使用的是swift

(ps:以下練習中代碼實現部分並不是唯一解答方法,僅供參考)

Two Sum

題目鏈接
題目大意:給定一個整數數組,找出滿足兩個數字相加 等於 目標數的兩個數字的索引,並且返回。
例如:

nums = [2, 7, 11, 15], target = 9 ,
因為 nums[0] + nums[1] = target,
所以 return [0, 1]

代碼實現:

func twoSum(_ nums:[Int], _ target:Int) -> [Int]? {
    var d = [Int: Int]()
    
    for (i, num) in nums.enumerated(){
        if let sum = d[target - num] {
            return [sum, i]
        }else{
            d[num] = i
        }
    }
    return nil
}

Add Two Numbers

題目鏈接
題目大意:使用鏈表實現兩個數字相加

例如:

12 + 13 = 25

代碼實現:

public class ListNode {
    public var val: Int
    public var next: ListNode?
    public init(_ val: Int) {
        self.val = val
        self.next = nil
    }
}

public class Solution {
    func addTwoNumbers(_ l1:ListNode?, _ l2:ListNode?) -> ListNode? {
        return helper(l1, l2, 0)
    }
    
    func helper(_ l1:ListNode?, _ l2:ListNode?, _ carry: Int) -> ListNode? {
        var p = l1
        var q = l2
        
        if p == nil && q == nil {
            return carry == 0 ? nil: ListNode(carry)
        }
        
        if p == nil && q != nil {
            p = ListNode(0)
        }
        
        if p != nil && q == nil {
            q = ListNode(0)
        }
        
        let sum = (p?.val)! + (q?.val)! + carry
        let curr = ListNode(sum % 10)
        curr.next = helper(p?.next, q?.next, sum/10)
        return curr
    }
}

var l1:ListNode?
var l2:ListNode?

l1 = ListNode(12)
l2 = ListNode(13)

let s = Solution()
let result1 = s.addTwoNumbers(l1, l2)

思路:

按照小學加法原理,從末尾對齊相加,滿十進位。技巧在於如何處理不同長度的兩個數字,以及進位和最高位的判斷。這里對於不同長度的數字,我們通過在較短的數字前面添加零來保證每一位都能相加。主要分為以下3個要點:

  • 全部為nil時,返回進位值;
  • 有一個為nil時,返回不為nil的那個ListNode和進位值相加的結果;
  • 都不為nil時,返回兩個ListNode和進位值相加的結果。

Longest Substring Without Repeating Characters

題目鏈接

題目大意:給定一個字符串,找出其中最長的沒有出現重復字符的連續子串的長度。
例如:

"abcabcbb" 最長的不重復字符子串是"abc",長度為3;
"bbbbb" 最長的不重復字符子串是"b",長度為1;
"pwwkew" 最長的不重復字符子串是"wke",長度為3;

代碼實現:

func lengthOfLongestSubstring(_ s:String) -> Int {
    if s.isEmpty {
        return 0
    }
    
    var map = [Character: Int]()
    var result = 0
    var j = 0
    
    for (i, charactor) in s.characters.enumerated() {
        if map.keys.contains(charactor) {
            j = max(j, map[charactor]! + 1)
        }
        
        map[charactor] = i
        result = max(result, i-j+1)
    }
    
    return result
}

思路:

本題目主要有3個注意點:

  1. 最長的;
  2. 連續的;
  3. 沒有重復的字符;

致謝

如果發現有錯誤的地方,歡迎各位指出,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM