• 力扣题目学习笔记(OC + Swift)


    训练思维,提高编程能力,不为刷题而刷题

    1. 两数之和

    给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那 两个 整数,并返回它们的数组下标。
    你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
    你可以按任意顺序返回答案。

    Swift版本

    class Solution {
        func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
            var map = [Int : Int]()
            
            for (i, e) in nums.enumerated() {
                if let u = map[target - e] {
                    return [u, i]
                }else {
                    map.updateValue(i, forKey: e)
                }
            }
            
            return []
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    OC版本

    - (NSArray *)twoSum:(NSArray *)nums target:(NSInteger)target {
        
        NSMutableDictionary *mutDic = [NSMutableDictionary dictionary];
        
        __block NSArray *result = nil;
        [nums enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            NSNumber *num = mutDic[@(target - obj.integerValue)];
            if (num) {
                result = @[num, @(idx)];
                *stop = YES;
            }else {
                mutDic[obj] = @(idx);
            }
        }];
        return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试代码:

    NSArray *testArr = [NSArray arrayWithObjects:@(2),@(7),@(11), @(15), nil];
        NSArray *resu = [self twoSum:testArr target:18];
        if (resu) {
            NSLog(@"找到结果:%ld, %ld", [resu[0] integerValue], [resu[1] integerValue]);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. 两数相加

    给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
    请你将两个数相加,并以相同形式返回一个表示和的链表。
    你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    Swift实现

    class Solution {
        func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
            var listNode1 = l1;
            var listNode2 = l2;
            
            //进位
            var carry: Int = 0;
            
            let result: ListNode = ListNode(0)
            var currentNode = result
            
            while listNode1 != nil || listNode2 != nil || carry > 0 {
                let sum: Int = (listNode1?.val ?? 0) + (listNode2?.val ?? 0) + carry
                currentNode.next = ListNode(sum % 10)
                currentNode = currentNode.next!
                
                listNode1 = listNode1?.next
                listNode2 = listNode2?.next
                carry = sum / 10
            }
            
            return result.next
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    OC实现

    - (ListNode *)addTwoNumber:(ListNode *)l1 listNode2:(ListNode *)l2 {
        ListNode *result = [[ListNode alloc] initWithVal:0];
        ListNode *currentNode = result;
        
        ListNode *listNode1 = l1;
        ListNode *listNode2 = l2;
        
        //进位标记
        NSInteger carry = 0;
        
        while (listNode1 || listNode2 || carry > 0) {
            NSInteger sum = listNode1.val + listNode2.val + carry;
            currentNode.next = [[ListNode alloc] initWithVal:sum%10];
            currentNode = currentNode.next;
            
            listNode1 = listNode1.next;
            listNode2 = listNode2.next;
            carry = sum / 10;
        }
        
        return result.next;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3.无重复字符的最长子串

    给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

    Swift

    /*
     * 滑动窗口法
     */
    func lengthOfLongestSubstring(_ s: String) -> Int {
            
            let strlen = s.count
            let chs: [Character] = Array(s)
        
            var map = [Character : Int]()
            var start = 0
            
            var maxLen: Int = 0
            for i in 0..<chs.count {
                let char = chs[i]
                if let preIdx = map[char] {
                    start = max(start, preIdx+1)
                }
                
                map[char] = i;
                maxLen = max(maxLen, i-start+1)
                
                print(start, maxLen)
            }
            
            return maxLen
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    OC

    /*
     * 滑动窗口法
     */
     - (NSInteger)lengthOfLongestSubstring:(NSString *)s {
        if (s.length < 2) {
            return s.length;
        }
        
        NSInteger strLen = s.length;
        NSInteger maxLen = 0;
        NSInteger start = 0;
        NSMutableDictionary *map = [NSMutableDictionary dictionary];
        
        for (NSInteger i=0; i
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    4.寻找两个正序数组的中位数

    给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
    算法的时间复杂度应该为 O(log (m+n)) 。

    Swift

    class Solution {
        func findMedianSortedArrays(_ nums1: [Int], _ nums2: [Int]) -> Double {
            let totalLen = nums1.count + nums2.count;
            
            if totalLen % 2 == 0 {
                let sum = getKthElement(num1: nums1, num2: nums2, kth: (totalLen+1)/2) + getKthElement(num1: nums1, num2: nums2, kth: (totalLen+2)/2)
                return Double(sum) / 2.0
            }else {
                let res = getKthElement(num1: nums1, num2: nums2, kth: (totalLen+1)/2)
                return Double(res)
            }
        }
        
        
        /* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
         * nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
         * nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
         * 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
         * 这样 pivot 本身最大也只能是第 k-1 小的元素
         * 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
         * 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
         * 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
         */
        func getKthElement(num1: [Int], num2:[Int], kth: Int) -> Int {
            let m: Int = num1.count
            let n: Int = num2.count
            var k = kth
            
            var index1: Int = 0, index2: Int = 0
            
            while true {
                
                //处理边界情况
                if index1 == m {
                    return num2[index2 + k - 1]
                }
                
                if index2 == n {
                    return num1[index1 + k - 1]
                }
                
                if k == 1 {
                    return min(num1[index1], num2[index2])
                }
                
                //处理正常情况
                let newIdx1: Int = min(index1 + k/2 - 1, m-1)
                let newIdx2: Int = min(index2 + k/2 - 1, n-1)
                
                let pivot1 = num1[newIdx1]
                let pivot2 = num2[newIdx2]
                
                if pivot1 <= pivot2 {
                    k -= newIdx1 - index1 + 1
                    index1 = newIdx1 + 1
                }else {
                    k -= newIdx2 - index2 + 1
                    index2 = newIdx2 + 1
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    OC

    - (CGFloat)findMedianSortedArraysWithNums1:(NSArray *)num1 nums2: (NSArray *)num2 {
        
        NSInteger totalLength = num1.count + num2.count;
        if (totalLength % 2 != 0) {
            return [self getKthElement:num1 arr2:num2 kth:(totalLength+1)/2];
        }else {
            CGFloat result = ([self getKthElement:num1 arr2:num2 kth:(totalLength+1)/2] + [self getKthElement:num1 arr2:num2 kth:(totalLength+2)/2])/2.0;
            return result;
        }
    }
    
    /* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
     * 这里的 "/" 表示整除
     * nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
     * nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
     * 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
     * 这样 pivot 本身最大也只能是第 k-1 小的元素
     * 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
     * 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
     * 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
     */
    - (NSInteger)getKthElement:(NSArray *)num1 arr2:(NSArray *)num2 kth:(NSInteger)k {
        NSInteger m = num1.count;
        NSInteger n = num2.count;
        
        NSInteger index1 = 0, index2 = 0;
        
        while (true) {
            
            //处理边界情况
            if (index1 == m) {
                NSNumber *num = num2[index2 + k - 1];
                return [num integerValue];
            }
            
            if (index2 == n) {
                NSNumber *num = num1[index1 + k - 1];
                return [num integerValue];
            }
            
            if (k == 1) {
                return MIN([num1[index1] integerValue], [num2[index2] integerValue]);
            }
            
            
            //正常情况
            NSInteger newIndex1 = MIN(index1+k/2-1, m-1);
            NSInteger newIndex2 = MIN(index2+k/2-1, n-1);
            NSInteger pivot1 = [num1[newIndex1] integerValue];
            NSInteger pivot2 = [num2[newIndex2] integerValue];
            
            if (pivot1 <= pivot2) {
                k -= newIndex1 - index1 + 1;
                index1 = newIndex1 + 1;
            }else {
                k -= newIndex2 - index2 + 1;
                index2 = newIndex2 + 1;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
  • 相关阅读:
    Python的数据分析包Pandas?示例文章完成版来啦~
    cookie和session的区别,分布式环境怎么保存用户状态
    利用C++11 实现:迷你线程池+CAS自旋锁
    百度地图 缩放 0.5 zoomend zoom_changed
    以脚本形式运行python库
    Qt QSS基本属性样式表半通关
    Java 中 Cloneable 接口和 clone() 方法的使用
    VCS(DVE)仿真波形的存储和打开.vpd
    HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList的底层实现。
    【MyBatis】缓存——使查询变得快快快!
  • 原文地址:https://blog.csdn.net/zzl819954692/article/details/134537892