zoukankan      html  css  js  c++  java
  • [Swift]编码拾遗

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10978800.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    1、寻找重复出现奇数次的数字。

    给定一个整形数组,其中只有一个数字出现奇数次,其他数字出现偶数次。找出这个数字?

    思考:两个相同的整数异或为零,一个整数和0异或为其本身。异或可以使用交换律和结合律。

    例:数组[1,1,2,2,2,3,3,3,3]求出现了奇数次的数字。

    1^1^2^2^2^3^3^3^3 

    =(1^1)^(2^2)^2^(3^3)^(3^3) 

    =0^0^2^0^0

    =2

    Talk is cheap.Show me your code:

    1 //测试用例
    2 let arr = [1,1,2,2,2,3,3,3,3]
    3 //打印
    4 print(arr.reduce(0,^))
    5 //Print 2

    2、不使用额外辅助变量,如何交换两个整型变量x和变量y的值?

    思考:异或可以使用交换律和结合律。

    1 x = x ^ y  (​1)
    2 y = x ^ y  (2)
    3 x = x ^ y  (3)

    证明:将式1分别代入式2、式3

    1 y = x^y = (x^y)^y = x^(y^y) = x^0 = x
    2 x = x^y = (x^y)^x = (x^x)^y = 0^y = y

    Talk is cheap.Show me your code:

    1 func swap(_ x:inout Int,_ y:inout Int)
    2 {
    3     x = x ^ y
    4     y = x ^ y
    5     x = x ^ y
    6 }

    测试:

    1 var x:Int = 1
    2 var y:Int = 9
    3 swap(&x,&y)
    4 print(x)
    5 //Print 9
    6 print(y)
    7 //Print 1

    3、不使用pow库函数,求m的n次方?

    例:求m的7(二进制:111)次方?

    可以拆解为:m^7=(m^100)*(m^010)*(m^001)

    通过[&1]和[>>1]来逐位读取指数,为1时将该位代表的指数累乘到最终结果中。

    Talk is cheap.Show me your code:

     1 func newPow(_ m:Int,_ n:Int) -> Int
     2 {
     3     var m = m
     4     var n = n
     5     var sum:Int = 1
     6     while(n != 0)
     7     {
     8         if n & 1 == 1
     9         {
    10             sum *= m
    11         }
    12         m *= m
    13         n = n >> 1
    14     }
    15     return sum
    16 }

    测试:

    1 print(newPow(3,4))
    2 //print 81

    4、取模运算和取余运算的区别

    取余运算和取模运算的步骤相同。

    对于整数a、b。计算a%b:

    (1)、求商: c = a/b;

    (2)、计算模或余数: r = a - c*b.

    求模运算和求余运算在第一步不同: 

    取余运算在取c的值时,向0方向舍入;

    取模运算在计算c的值时,向-∞方向舍入。

    %在Swift、C、C++,Java 中称为余运算符,在Python中成为的模运算符。

    取余运算:Swift、C、C++,Java 

    取模运算:Python

    Swift是取余运算。若b负值,忽略b的符号。即:a % b = a % (-b)

    [总结]

    当a和b符号一致时:

    取余运算和取模运算所得结果一致。

    当a和b符号不一致时:

    取余运算结果和a符号一致。

    取模运算结果和b符号一致。

    测试:

    1 print(6%4)
    2 print(-6%4)
    3 print(6%(-4))
    4 //Print 2
    5 //Print -2
    6 //Print 2

    5、数组下标(计数排序):统计数字、判断字母出现次数。

    给定一个整形数组,数组元素的取值范围0~100。

    请用O(n)时间复杂度,从小到大打印出来?

    思路:把对应的数值作为数组下标,如果这个数出现过,则对应的数组加1。

    Talk is cheap.Show me your code: 

     1 func printNum(_ arr:[Int],_ maxNum:Int)
     2 {
     3     var temp:[Int] = [Int](repeating: 0, count: maxNum + 1)
     4     for i in 0..<arr.count
     5     {
     6         temp[arr[i]] += 1
     7     }
     8     for i in 0...maxNum
     9     {
    10         for j in 0..<temp[i]
    11         {
    12             print("(j):(i)")
    13         }
    14     }
    15 }

    测试:

     1 let arr:[Int] = [100,5,71,89,66,77,89,91,71,95,5,100]
     2 printNum(arr, 100)
     3 /*
     4 0:5
     5 1:5
     6 0:66
     7 0:71
     8 1:71
     9 0:77
    10 0:89
    11 1:89
    12 0:91
    13 0:95
    14 0:100
    15 1:100
    16 */

    5、递归(n->1)和递推(1->n)

    青蛙一次可以跳1级台阶或2级台阶。求该青蛙跳上n级的台阶有多少种跳法?

    递归(n->1)法:很多重复计算

    1 func jump(_ n:Int) -> Int
    2 {
    3     if n <= 2 {return n}
    4     else
    5     {
    6         return jump(n - 1)  +  jump(n - 2)
    7     }
    8 }

    测试:

    1 print(jump(10))
    2 //print 89

    备忘录法:巧用数组下标,去除重复计算

    当arr[n] = 0时,表示jump(n)未计算,

    当arr[n] != 0时,表示jump(n)已计算。

     1 func jump(_ n:Int) -> Int
     2 {
     3     var arr:[Int] = [Int](repeating: 0, count: 1)
     4     if n <= 2 {return n}
     5     else
     6     {
     7         //数组自动扩容
     8         while(n > arr.count - 1)
     9         {
    10             arr += [Int](repeating: 0, count: arr.count)
    11         }
    12         //未计算
    13         if arr[n] == 0
    14         {
    15             arr[n] = jump(n-1) + jump(n-2)
    16             return arr[n]
    17         }
    18         else
    19         {
    20             //已计算
    21             return arr[n]
    22         }
    23     }
    24 }

    测试:

    1 print(jump(10))
    2 //print 89
    3 print(jump(11))
    4 //print 144

    递推(1->n)法:

     1 func jump(_ n:Int) -> Int
     2 {
     3     if n <= 2 {return n}
     4     var n1:Int = 1
     5     var n2:Int = 2
     6     var sum:Int = 0
     7     for _ in 3...n
     8     {
     9         sum = n1 + n2
    10         n1 = n2
    11         n2 = sum
    12     }
    13     return sum
    14 }

    测试:

    1 print(jump(10))
    2 //print 89
    3 print(jump(11))
    4 //print 144
    5 print(jump(12))
    6 //print 233

    使用递归时常考虑以下问题:

    (1). 是否有重复计算,可使用备忘录法来优化。

    (2). 是否可采取递推(1->n)的方法,减少递归的开销。

  • 相关阅读:
    Android开发过程中的坑及解决方法收录(二)
    【转】Android开发之数据库SQL
    Android开发过程中的坑及解决方法收录(一)
    Android开发之基于监听的事件处理
    Android开发——导入github安卓项目源码
    Android开发之常见事件响应方式
    Android studio导入eclipse项目(亲测)
    Android开发——diglog cancel与dismiss方法区别
    Android开发——Toast知识
    android 点击返回键 以及 加载activity 生命周期 记录。。。,一目了然
  • 原文地址:https://www.cnblogs.com/strengthen/p/10978800.html
Copyright © 2011-2022 走看看